이벤트 중심 마이크로 서비스 아키텍처에서 변경 처리


9

이벤트 중심 마이크로 서비스 아키텍처의 변경 사항을 처리 할 수있는 옵션을 연구하는 리서치 프로젝트를 진행하고 있습니다.

우리가 4 가지 다른 서비스를받는 애플리케이션을 가지고 있다고 가정 해 봅시다. 이러한 각 서비스에는 로컬 데이터를 저장하기위한 자체 데이터베이스가 있습니다.

이 설정에서 4 개의 서비스는 이벤트 버스를 사용하여 서로 통신합니다. 따라서 서비스에서 어떤 일이 발생하면 이벤트를 게시합니다. 해당 이벤트에 관심이있는 다른 모든 서비스는 고유 한 방식으로 처리합니다.

이 경우 아키텍처의 서로 다른 서비스는 이러한 이벤트의 내용 (속성 등)에 대한 "계약"을 가져야합니다. 따라서 서비스는 이러한 이벤트에 "느슨하게 결합 된 종속성"을 갖습니다.

내 질문은 : 이 이벤트에서 변경 사항을 어떻게 처리 할 수 ​​있습니까?

서비스 A가 응용 프로그램에 새 사용자를 등록한다고 가정 해 봅시다. 따라서 ""UserRegistered "이벤트를 전송합니다. 서비스 B가 해당 이벤트를 선택하여 처리하지만 서비스 C 팀의 일부 개발자는 등록 된 사용자의 성별도 필요하다고 결정했습니다. 따라서 이벤트가 변경되고 속성 성별 "UserRegistered"이벤트에 추가됩니다.

서비스 B가 재배치하지 않고 해당 추가 속성으로 동일한 이벤트를 계속 픽업 할 수 있도록하려면 어떻게해야합니까?

그리고이 문제에 접근 한 다음 이러한 이벤트를 버전 화하는 다른 방법이 있습니까?


메시지는 어떤 형식입니까, 아니면 디자인 할 수있는 것입니까? 일부 메시지 형식은 선택적 속성을 허용합니다. 리더의 구현에 따라 모든 리더를 업데이트하지 않고도 선택적 속성을 추가 할 수 있습니다.
Thomas Owens

메시지에 사용할 형식을 자유롭게 선택할 수 있습니다. JSON을 사용하는 것이 가장 좋은 방법이라고 생각합니다. 이러한 서로 다른 서비스는 서로 다른 언어로 구축되어야합니다. XML 또는 JSON과 같은 일반적인 형식이 필요한 이유입니다.
CGeense

답변:


1

사건은 무엇이 바뀌 었는지에 관한 것이 아닙니다. 그들은 무언가가 바뀌었을 때입니다.

변경된 내용과 완전히 분리 된 이벤트 시스템을 만들 수 있습니다. 내가 이벤트에서 배운 모든 것은 객체가 업데이트되었다는 것입니다. 객체가 업데이트되었다고 신경 쓰면 객체와 대화하는 방법을 알고 무엇이 바뀌 었는지 물어볼 것입니다.

이러한 변경 내용을 전달하는 문제는 해결되지 않습니다. 이벤트 시스템의 일부가되는 것을 막을뿐입니다.

다른 버전의 데이터 문제를 해결하는 한 가지 방법의 예는 관찰자가 관찰 된 개체를 수집하여 수집하도록하는 것입니다. 관찰 된 개체는 컬렉션을 최신 데이터로 채우고 제어가 반환되면 (관찰자) 필요한 것을 갖습니다. 당신이 신경 쓰지 않는 여분의 것이 있다면, 들어 본 적이 없기 때문에 단순히 무시하십시오.

그 고양이를 껍질을 벗기는 다른 많은 방법들이 있지만 그것은 바로이 경우에 효과를 발휘 한 방법입니다.


이것이 서비스 간의 트래픽을 크게 증가시키지 않습니까? 문제의 예에서 UserRegistered이벤트를 사용하면 사용자에 대한 정보가 포함되지 않은 이벤트가있는 경우 버스에 게시 된 메시지가 1 개 있고 사용자 서비스에 대한 {관심 서비스 수} 요청 또는 게시 된 메시지가 있습니다. 버스로. 그런 다음 다양한 크기의 {관심있는 서비스 수} 메시지가 표시됩니다. 나는 이것이 종이에 깔끔한 디자인이라고 생각하지만 성능이 문제가된다면 사소한 시스템, 특히 네트워크를 통해 고장납니다.
Thomas Owens

@ThomasOwens 이벤트와 함께 데이터를 보내는 것은 N 관찰자가 있으면 N 메시지를 보냅니다. 이벤트를 단독으로 보내는 것은 3N 메시지 중 하나만 데이터 패킷을 가지고 있다는 것을 의미합니다. 네트워크에서도 잘 확장됩니다. 유일하게 중요한 단점은 지연이 3 배라는 점입니다. 특정 상황에 맞는 최적의 솔루션을 찾을 수 없다고 말하는 것은 아닙니다. 이벤트 시스템과 데이터 버전을 연결할 필요가 없음을 증명하고 있습니다.
candied_orange

1
이 이벤트 버스의 전체 아이디어는 서로 다른 서비스를 분리하는 것입니다. 미들웨어를 사용하면 이러한 서비스가 서로를 알지 못하도록하고 서로의 존재를 알지 않고도 존재할 수 있고 통신 할 수 있습니다. 이러한 이벤트에서 상태를 제거하고 서비스가 서로 직접 연결되도록하면 이러한 서비스가 연결됩니다. 그렇게하면 나머지를 재배치 할 필요없이 단일 서비스를 재배치 할 수 없습니다.
CGeense

1
요점은 이벤트 시스템인지, 확장 가능한 데이터가 필요하지 않은지입니다. JSON 또는 XML은 이전에 설정된 이름이나 구조를 변경하지 않으면 잘 작동합니다. 나는 컬렉션과 똑같이했습니다. 이벤트 시스템은 성별에 관심이 없어야합니다. 데이터를 전송하는 경우 데이터를 전달해야하며 다른 쪽 끝은 성별에 관심이 있거나 그렇지 않습니다.
candied_orange

1

NServiceBus와 같은 프레임 워크는 다형성 메시지 디스패치와 함께 이벤트 버전 관리를 사용하여이를 처리합니다.

예를 들어, 서비스 A 버전 1은 이벤트를 IUserRegistered_v1로 게시 할 수 있습니다. 서비스 A 버전 1.1은 추가 필드를 포함해야하는 경우 IUserRegistered_v1에서 상속하고 일부 추가 필드를 선언하는 IUserRegistered_v1_1 인터페이스를 선언 할 수 있습니다.

서비스 A가 IUserRegistered_v1_1 이벤트를 게시하면 NServiceBus는 IUserRegistered_v1 또는 IUserRegistered_v1_1을 처리하는 모든 엔드 포인트로 메시지를 발송합니다.


0

증분 개선

모델의 간단한 변경은 청취자가 관찰자로 등록 할 때 알고 자하는 데이터 요소의 목록 또는 기타 구조를 포함한다는 것입니다. 이는 서비스에서 반환 된 데이터가 단순 할 경우 작동 할 수 있지만 상당한 양의 계층 데이터가있는 경우 구현하기가 매우 복잡해질 수 있습니다.

바위처럼 단단한

이 디자인을 수행하는 강력한 방법을 원한다면 서비스가 저장 한 데이터에 대한 변경 기록을 유지하도록하십시오. 기본적으로 데이터베이스에서 레코드를 업데이트하지 않으며 각각이 변경을 나타내는 새 레코드를 추가합니다. 이러한 각 새 레코드는 조치를 식별하는 이벤트 ID와 연관됩니다. 짝수 레코드에는 변경에 대한 모든 관련 정보 (누가, 무엇을, 언제 등)가 저장됩니다.이 답변의 범위를 벗어난 다른 이점이 있지만이 기사에서 CAP 정리에 대해 설명 합니다.

변경하면 이벤트 레코드를 작성하고 모든 새 데이터를 데이터베이스에 추가하십시오. 그런 다음 이벤트 ID가 포함 된 리스너에 이벤트를 게시합니다. 리스너는 해당 ID와 연관된 데이터를 요청하고 연관된 ID의 버전을 얻을 수 있습니다. 그러면 각 리스너는 다른 리스너의 요구를 서로 결합하지 않고도 필요한 것을 얻을 수 있습니다. 리스너가 관심없는 이벤트를 필터링 할 수 있도록 가장 일반적으로 사용되는 데이터 필드의 하위 세트를 이벤트 메시지에 추가하는 것이 좋습니다. 이렇게하면 프로세스의 대화가 줄어들고 일부 리스너는 호출 할 필요가 없습니다. 전혀 다시. 또한 타이밍 문제로부터 사용자를 보호합니다. 서비스에 전화를 걸어 키를 기준으로 데이터를 얻는다면, 이벤트 가져 오기와 이벤트 검색 사이에 다른 변경 사항이있을 수 있습니다. 모든 청취자에게 중요하지는 않지만 모든 변경 사항을 알아야 할 경우 큰 문제가 발생할 수 있습니다. 위의 점진적 디자인 개선은 실제로 11로 바꾸려는 경우이 접근법과 호환됩니다.

시간이 지남에 따라 레코드가 어떻게 변하는지를 정확하게 볼 수있는 방법이 없다면 내 경험상이 중 일부는 과도 할 수 있지만 데이터 작업을하는 사람은 결국 그것을 원할 것입니다.


-1

@CandiedOrange는 xml과 같은 확장 가능한 데이터 형식과 관련하여 자신의 답변에 대한 주석에서 유효한 지적을합니다.

데이터를 추가하는 한 중요하지 않습니다. 그러나 이전 이벤트 / 필수 필드에 적절한 기본값을 제공하십시오.

성별에 관심이있는 서비스 (이 경우에는 성별) 만 업데이트하면됩니다. xml / json 파서는 다른 서비스에 대한 추가 데이터를 무시할 수 있어야합니다. 물론 선택한 파서 및 이벤트 데이터 형식에 따라 다릅니다.

그래도 관련 데이터가없는 이벤트에는 동의하지 않습니다. 이벤트 소싱의 경우 이벤트는 변경된 사항을 정의해야합니다. 이벤트를 수신하면 다른 서비스가 이벤트 소스에서 데이터를 검색 할 필요가 없습니다.


요점은 모든 종류의 변경을 처리해야한다는 것입니다. 이벤트를 방송하는 서비스를 생각해보십시오. 그리고 해당 이벤트에는 더 이상 사용되지 않으며 제거해야하는 속성이 포함됩니다. 이러한 다른 서비스가 해당 속성을 사용하지 않더라도 예상 한 것이므로 단순히 중단됩니다. 따라서 martinfowler.com에서 소비자 중심 계약에 대한이 기사를 읽었습니다. martinfowler.com/articles/consumerDrivenContracts.html 이 원칙을 적용 할 때. 각 제공자 (이벤트)는 자신에게 기대되는 것을 알고 있습니다. 그 정보와 함께 그는 자신의 소비자를 깰 경우 유효성을 검사 할 수 있습니다.
CGeense
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.