마이크로 서비스에서 DTO를 공유하는 방법은 무엇입니까?


33

내 시나리오는 다음과 같습니다.

다양한 유형의 센서에서 데이터를 수신하고 나중에 다양한 프런트 엔드 및 분석 서비스에서 사용하도록 변환 및 유지하도록 설계된 시스템을 설계하고 있습니다.

모든 서비스를 가능한 한 독립적으로 디자인하려고 노력하고 있지만 문제가 있습니다. 팀은 우리가 사용할 DTO를 결정했습니다. 외부를 향한 서비스 (센서 데이터 수신자)는 고유 한 방식으로 데이터를 수신 한 다음 JSON 객체 (DTO)로 변환하여 Message Broker로 보냅니다. 그러면 메시지 소비자는 센서 데이터 메시지를 읽는 방법을 정확하게 알게됩니다.

문제는 몇 가지 다른 서비스에서 동일한 DTO를 사용하고 있다는 것입니다. 여러 위치에서 업데이트를 구현해야합니다. 분명히, 우리는 여기에 DTO에 몇 가지 추가 또는 누락 된 필드가 있고 서비스가 업데이트 될 때까지 많은 문제가 발생하지 않도록 설계했지만 여전히 버그가 발생하여 기분이 좋아집니다. 실수하기. 두통으로 쉽게 변할 수 있습니다.

시스템을 잘못 설계하려고합니까? 그렇지 않다면,이 문제를 해결하는 방법은 무엇입니까, 아니면 적어도 걱정을 덜어주는 방법은 무엇입니까?


어떤 종류의 DTO를 공유하고 있으며 서비스간에 어떤 프로토콜을 사용하고 있습니까? 예를 들어 protogRPC 용 파일 또는 avroKafka 용 스키마를 공유하고 두 서비스 모두에서 DTO를 생성하는 것은 좋지만 두 프로젝트간에 공유 라이브러리는 공유하지 않습니다.
Vincent Savard

인코딩 된 JSON 문자열 및 AMQP 언어별로 사용하지 않는 것이 좋습니다.
nbaughman

답변:


38

나의 충고? 모든 종류의 라이브러리에있는 응용 프로그램간에 이러한 DTO를 공유하지 마십시오 . 또는 적어도 지금 당장하지 마십시오.

나는 매우 반 직관적 인 것처럼 보인다. 코드를 복제하고 있습니까? 그러나 이것은 비즈니스 규칙이 아니므로 더 유연해질 수 있습니다.

DTO를 전송하는 서비스는 메시지 계약에서 Rest API와 같이 엄격해야합니다. 이 서비스는 DTO에서 이미 정보를 소비하는 다른 서비스를 중단시킬 수있는 방식으로 DTO를 변경할 수 없습니다.

새로운 필드가 DTO 할 추가 할 때, 당신은이 DTO를 소비하는 다른 서비스를 업데이트 할 경우 그들이 새로운 분야를 필요로합니다. 그렇지 않으면 잊어 버리십시오. 콘텐츠 유형으로 JSON을 사용하면 실제 버전의 DTO에 이러한 새 필드를 매핑하지 않는 서비스 코드를 손상시키지 않고 새로운 속성을 생성하고 전송할 수있는 유연성이 있습니다.

그러나이 상황이 실제로 귀찮은 경우 세 가지 규칙을 따를 수 있습니다 .

재사용에는 "3 가지 규칙"이 두 가지 있습니다. 재사용 라이브러리에 동의합니다.

따라서 서비스간에이 DTO를 공유하기 전에 조금 더 기다리십시오.


1
대단히 감사합니다. 이것은 제가 앞으로 진행할 주요 관심사 중 하나입니다. 밤에 나를 유지하기에는 충분하지 않지만 나를 걱정하기에 충분합니다.
nbaughman

4
서로 다른 매우 독립적 인 서비스의 중복 된 DTO는 DRY를 위반하지 않습니다. 그게 다야.
Laiv

3
아마도 단 한 번의 작업으로 DTO 소스 코드를 한 프로젝트에서 다른 프로젝트로 직접 복사하지 않는 이유는 없지만 새 프로젝트에 필요하지 않은 부분은 삭제해야 할 것입니다.
bdsl

1
전체 서비스조차 삭제되어 전체 시스템에 큰 문제가 발생하지 않을 수 있습니다. 이상적으로
Laiv

4
응답의 본질을 명확히하기 위해, 마이크로 서비스를 개발할 때 각 서비스는 실제 계약을 제외하고 다른 서비스에 대해 알지 못하는 것처럼 개발되어야합니다.
Jonathan van de Veen

12

마이크로 서비스와 관련하여 서비스의 개발 수명 주기도 독립적이어야합니다. *

다른 SLDC 및 다른 개발 팀

실제 MS 시스템에는 하나 이상의 서비스를 담당하는 생태계 개발과 관련된 여러 팀이있을 수 있습니다. 이 팀들은 서로 다른 사무실, 도시, 국가, 계획에 위치 할 수 있습니다. 아마도 그들은 서로를 알지 못해 지식이나 코드를 공유하는 것이 매우 어렵습니다 (가능한 경우). 그러나 이것은 공유 코드가 일종의 공유 추론을 의미하기 때문에 매우 편리 할 수 ​​있습니다. 특정 팀에 적합한 것이라도 다른 팀에 대해 그것을 만들 필요가 없다는 점을 기억해야합니다. 예를 들어, DTO Customer가 주어지면 고객 은 서비스마다 다르게 해석 (또는보기) 되기 때문에 사용중인 서비스에 따라 다를 수 있습니다 .

다른 요구, 다른 기술

또한 격리 된 SLDC를 통해 팀은 필요에 가장 적합한 스택을 선택할 수 있습니다. 특정 기술로 구현 된 DTO를 적용하면 팀의 선택 능력이 제한됩니다.

DTO는 비즈니스 규칙이나 서비스 계약이 아닙니다.

실제로 어떤 DTO입니까? 한 쪽에서 다른쪽으로 데이터를 이동하는 것 외에 다른 목표가없는 일반 개체. 게터와 세터의 가방. 전혀 지식이 없기 때문에 재사용 할 가치가있는 "지식"이 아닙니다. 그들의 휘발성은 또한 커플 링의 나쁜 후보가됩니다.

Dherik의 말과 달리 서비스가 다른 서비스를 동시에 변경하지 않고도 DTO를 변경할 수 있어야합니다 . 서비스 관대 한 독자, 관용 작가 및 내약성 이어야 합니다 . 그렇지 않으면 서비스 아키텍처가 의미가없는 방식으로 연결됩니다. Dherik의 답변과는 달리, 세 개의 서비스에 정확히 동일한 DTO가 필요한 경우 서비스 분해 중에 문제가 발생한 것 같습니다.

다른 사업, 다른 해석

서비스간에 교차 개념이있을 수 있지만 모든 서비스가 동일한 방식으로 해석하도록 강제 모델을 적용해야한다는 의미는 아닙니다.

사례 연구

우리 회사에 고객 서비스 , 판매배송 부서가 있다고 가정 해 봅시다 . 이 릴리스들 각각에 하나 이상의 서비스가 있다고 가정하십시오.

고객 서비스는 도메인 언어 로 인해 고객개인 인 고객 개념을 중심으로 서비스를 구현합니다 . 예를 들어 고객이름 , , 연령 , 성별 , 이메일 , 전화 등 으로 모델링됩니다 .

이제 영업배송 은 각 도메인 언어에 따라 서비스를 모델링합니다. 이러한 언어에서는 고객 개념이 나타나지만 미묘한 차이가 있습니다. 그들 에게 고객 은 (필수적으로) 사람 이 아닙니다 . 들어 판매 , 고객은이다 문서 번호 신용 카드청구 주소 에 대한, 배송 전체 이름배송 주소를 너무가.

우리가 강제하는 경우 판매배송 의 표준 데이터 모델을 채택하는 고객 서비스 , 우리는 그들이 전체 표현을 유지하고 유지해야하는 경우 불필요한 복잡성을 도입 끝낼 수 있었다 불필요한 데이터를 처리하도록 강제하는 고객 과 동기화 된 데이터를 고객 서비스 .

관련된 링크들


* 이 아키텍처의 장점은 다음과 같습니다.


고맙습니다! 사례 연구는 실제로 DTO 공유 여부를 결정하는 데 도움이되었습니다. 이제 왜 내가 공유하고 싶지 않은지 확신합니다.
Igor

8

모든 서비스를 가능한 한 독립적으로 디자인하려고합니다.

이벤트를 게시해야 합니다 . 이벤트는 특정 시점에 발생한 일에 대한 확실한 사실 을 나타내는 특정 유형의 메시지입니다 .

각 서비스는 명확하게 정의 된 책임이 있어야하며 해당 책임과 관련된 이벤트를 게시 할 책임이 있어야합니다.

또한 이벤트가 기술 이벤트가 아닌 비즈니스 관련 이벤트를 나타내기를 원합니다. 예를 들어와 함께 OrderCancelled이벤트를 선호합니다 .OrderUpdatedstatus: "CANCELLED"

이렇게하면 서비스가 취소 된 주문에 반응해야하는 경우 해당 이벤트와 관련된 데이터 만 전달하는 특정 유형의 메시지 만 수신하면됩니다. 예를 들어 OrderCancelled아마도 order_id. 이에 대응해야하는 서비스는 이미 주문에 대해 알아야 할 모든 것을 자체 데이터 저장소에 저장했습니다.

그러나 서비스 OrderUpdated에 수신 할 이벤트 만있는 경우, 이벤트 플로우를 해석해야하며 주문이 취소 될 때 올바르게 완료하기 위해 이제 배달 주문에 의존했습니다.

당신의 센서 데이터를 게시하는대로 귀하의 경우에는, 그러나, 그것은 서비스를하는 것이 만들 수, 이벤트를 수신하고 예를 들어, "비즈니스 이벤트"의 새로운 스트림을 게시 TemperatureThresholdExceeded, TemperatureStabilised.

너무 많은 마이크로 서비스를 작성하는 데주의하십시오. 마이크로 서비스는 복잡성을 캡슐화하는 좋은 방법이 될 수 있지만 적절한 서비스 경계를 ​​찾지 못하면 복잡성이 서비스 통합에 있습니다. 그리고 그것은 유지하는 악몽입니다.

너무 많거나 너무 작은 서비스를 사용하는 것보다 너무 적거나 너무 큰 서비스를 사용하는 것이 좋습니다.


나는 확실히 동의합니다. 센서 데이터는 마이크로 서비스로 곧바로 전달되어 메시지를 구문 분석하여 브로커에 게시하기 전에 조직 전체에서 동의 한 형식으로 변환합니다. 메시지를 읽고 데이터베이스에 유지하는 서비스와 메시지 분석을 수행하고 자체적으로 수행하는 서비스가 있습니다. 비즈니스의 특성상 각 서비스는 할 일이 많지 않기 때문에 (간단히) 매우 간단한 서비스로 연결됩니다.
nbaughman

2
@ Nickdb93-귀하의 경우 센서 데이터를 게시 할 때 서비스를 받고 이벤트를 듣고 새로운 "비즈니스 이벤트"스트림 (예 : TemperatureThresholdExceeded, TemperatureStabilised)을 게시하는 것이 좋습니다. (답변에 추가됨)
Pete
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.