이벤트 기반 아키텍처는 소수의 서비스 사이에서 제한적으로 사용되는 모델에서 광범위한 생산자, 소비자 및 메시지 채널의 네트워크로 변화하고 있다. 이 시점에서 핵심 문제는 더 이상 메시지를 전송하는 것이 아니라, 무엇이 전송되는지, 누가 소유하는지, 누가 이에 의존하는지, 그리고 프로덕션 장애를 일으키지 않고 스키마를 변경하거나 인프라를 재생성할 수 있는 방법을 파악하는 것이다. 이것이 Just Eat Takeaway의 실제 엔지니어링 관행을 바탕으로 대규모 비동기 API 관리에 대해 Ian Cooper가 진행한 세션의 핵심이다.
확장하면 왜 복잡해지는가?
소규모 조직에서는 팀원들이 이벤트를 게시하고 소비하는 서비스를 알고 있을 수 있으며, 메시징 프레임워크를 통해 또는 플랫폼 팀에 직접 요청하여 토픽이나 채널을 생성할 수도 있다. 그러나 팀과 서비스의 수가 늘어나면 이러한 방식은 효과를 잃는다. 특정 엔드포인트의 소유자가 누구인지, 메시지를 설명하는 계약이 무엇인지, 또는 데이터 및 분석 팀에 알려지지 않은 소비자가 있는지 명확하지 않을 수 있다.
알려진 소비자들과만 협의한 뒤 한 팀이 메시지 스키마를 변경할 때 위험이 발생한다. 다른 팀들이 소통 범위에 포함되지 않은 채 해당 메시지에 의존하고 있을 수 있기 때문이다. 특히 소유자를 파악하거나 필요한 인프라를 재게시하는 신뢰할 수 있는 방법이 없어 시스템의 상당 부분을 다시 배포해야 한다면, 사용되지 않는다고 여겨지는 토픽을 삭제하는 일은 중요한 경로의 손실로 이어질 수 있다.
이벤트 API 관리를 위한 세 가지 축
Cooper는 이 문제를 검색, 거버넌스, 프로비저닝으로 나눈다. 이는 그가 ‘ABCs’라고 부르는 내용을 통해 모든 엔드포인트에서 무엇을 설명해야 하는지 이해하는 것에서 시작한다. 주소는 메시지 흐름의 위치를 정하고, 바인딩은 프로토콜, 전송 및 인코딩을 설명하며, 계약은 메시지가 담는 헤더와 데이터를 정의한다.
이러한 맥락에서 AsyncAPI는 OpenAPI와 같은 HTTP API 문서화 메커니즘에 대응하는 기능을 제공하며, 프로토콜별 서버, 채널, 메시지, 작업 및 바인딩을 모델링한다. 또한 JSON Schema, Avro 및 Protobuf를 사용한 메시지 설명을 지원하고, 여러 파일에서 정의를 반복하는 대신 재사용할 수 있도록 한다. 그러나 Cooper는 수백 개의 AsyncAPI 파일을 하나의 저장소에 배치하는 것만으로는 검색 문제가 해결되지 않는다고 강조한다. 이벤트 자산이 커지면 텍스트 검색은 여전히 제한적이기 때문이다.
따라서 조직은 EventCatalog나 Marmot과 같은 카탈로그 도구 또는 xRegistry와 같은 개방형 레지스트리를 필요로 할 수 있다. 목적은 메시지 흐름과 그 관계를 표시하고 스키마를 생산자 및 소비자와 연결하는 것이다. 이러한 도구는 시각화 수준과 기본 제공 인터페이스에서 차이가 있지만, 공통된 기능은 검색을 Slack에서 질문하거나 여러 저장소에서 찾아야 하는 작업에서 쿼리 가능한 서비스로 전환하는 것이다.
메타데이터 표준화에서 CloudEvents의 역할
CloudEvents는 문제의 다른 측면을 담당한다. 식별자, 소스, 버전 및 유형과 같은 표준화된 메타데이터 집합을 제공하며, 데이터 콘텐츠 유형, 주제, 시간 및 스키마 링크를 위한 선택적 필드도 제공한다. 이벤트 유형은 메시지를 라우팅하거나 하나의 채널에서 여러 유형이 공유될 때 역직렬화 방식을 선택하는 데 사용할 수 있다.
세션에서는 CloudEvents의 binary 및 structured 모드가 메시지가 통상적인 의미에서 ‘바이너리’인지 ‘구조화’되었는지가 아니라, 전송 프로토콜이 헤더를 전달할 수 있는지와 관련된다고 설명한다. 이 세부 사항은 SNS와 같은 시스템에서 중요하다. 모든 CloudEvents 데이터를 헤더에 넣으면 제한된 수의 메시지 속성이 빠르게 소비될 수 있으므로, 일부 시나리오에서는 이를 본문 안에 래핑하는 것이 실용적인 선택이 된다.
거버넌스는 문서화에 국한되지 않는다
계약을 문서화하면 소비자에게 메시지의 내용을 알릴 수 있지만, 생산자가 소비자의 의존성을 깨뜨리는 변경 사항을 게시하는 것을 막지는 못한다. 따라서 제시된 접근 방식은 계약을 업데이트할 때 호환성 규칙을 적용하고, 승인된 규칙에 맞지 않는 메시지나 변경 사항을 거부하는 스키마 레지스트리를 사용할 것을 권장한다.
안전한 관행에는 일반적으로 필드를 선택 사항으로 추가하고, 모든 소비자가 해당 필드의 사용을 중단할 때까지 필드 삭제를 미루며, 이름 변경을 삭제와 추가로 구성된 변경으로 처리하는 것이 포함된다. 필드 유형 변경은 대개 호환성을 깨뜨리는 변경으로 간주된다. 원하는 유형의 새 필드를 추가한 다음 소비자를 새 필드로 이전하고, 이후 기존 필드를 제거하는 방식으로 실행할 수 있다.
실제로 무엇이 달라지는가?
기술 독자를 위한 핵심 메시지는 대규모 이벤트 관리에 단일 도구가 아니라 서로 연결된 체계가 필요하다는 것이다. 즉, API 설명을 위한 AsyncAPI, 메타데이터 표준화를 위한 CloudEvents, 검색을 용이하게 하는 카탈로그 또는 레지스트리, 호환성을 강제하는 스키마 레지스트리, 인프라를 프로비저닝하고 드리프트를 모니터링하는 자동화가 필요하다. 이러한 계층이 없으면 이벤트 기반 아키텍처는 보이지 않는 의존성의 네트워크로 변할 수 있다.
실질적인 제약도 남아 있다. 표준만으로는 소비자에 대한 완전한 정보를 제공하지 못하며, 도구마다 인터페이스, 시각화 및 브로커와의 통합 지원이 다르다. 따라서 이 접근 방식을 적용하려면 계약과 채널의 소유권을 명확히 정하고, 변경 사항을 CI/CD 프로세스에 연결하며, 개인의 지식이나 오래된 문서에 의존하지 않고 리소스를 재생성할 수 있는 복구 경로를 유지해야 한다.
뉴스 출처
InfoQ - Architecture Articles
원문 보기 ↗