마이크로 서비스 : 외래 키 관계를 처리하는 방법


85

마이크로 서비스 아키텍처는 각 서비스가 자체 데이터를 처리해야한다고 제안합니다. 따라서 다른 서비스 (서비스 B)가 소유 한 데이터에 의존하는 모든 서비스 (서비스 A)는 직접적인 DB 호출이 아닌 두 번째 서비스 (서비스 B)에서 제공하는 API를 통해 이러한 데이터에 액세스해야합니다.

따라서 마이크로 서비스 모범 사례는 외래 키 제한 검사에 대해 무엇을 제안합니까?

예 : 제품에 대한 제공 기능 (마이크로 서비스 1)을 개발 중이며 특정 제품은 제품 마이크로 서비스 (mircoservice 2)에만 액세스 할 수있는 제품 표에 언급 된 특정 위치에만 제공됩니다.

마이크로 서비스 1 (즉, 배달 기능)이 서비스되지 않은 위치로 주문을받지 않도록하려면 어떻게해야합니까? 배송 기능은 제품 데이터베이스에 직접 접근 할 수 없기 때문에 배송 주문이 배송 데이터베이스에있을 때 DB 수준에서 적용 가능한 제약이 없기 때문에이 질문이 있습니다. 또는 테이블).

답변:


71

여러 마이크로 서비스에 공유 데이터베이스를 사용할 수 있습니다. http://microservices.io/patterns/data/database-per-service.html 링크에서 마이크로 서비스의 데이터 관리 패턴을 찾을 수 있습니다 . 그건 그렇고, 마이크로 서비스 아키텍처에 매우 유용한 블로그입니다.

귀하의 경우 서비스 패턴별로 데이터베이스를 사용하는 것을 선호합니다. 이것은 마이크로 서비스를보다 자율적으로 만듭니다. 이 상황에서는 여러 마이크로 서비스간에 일부 데이터를 복제해야합니다. 마이크로 서비스간에 API 호출로 데이터를 공유하거나 비동기 메시징으로 공유 할 수 있습니다. 인프라 및 데이터 변경 빈도에 따라 다릅니다. 자주 변경되지 않는 경우 비동기 이벤트로 데이터를 복제해야합니다.

귀하의 예에서 배송 서비스는 배송 위치 및 제품 정보를 복제 할 수 있습니다. 제품 서비스는 제품과 위치를 관리합니다. 그런 다음 필요한 데이터가 비동기 메시지와 함께 Delivery Service의 데이터베이스에 복사됩니다 (예 : rabbit mq 또는 apache kafka를 사용할 수 있음). 배송 서비스는 상품 및 위치 데이터를 변경하지 않고 업무를 수행 할 때 데이터를 사용합니다. 택배 서비스에서 사용하는 제품 데이터의 일부가 자주 변경되는 경우 비동기 메시징으로 데이터를 복제하는 데 많은 비용이 듭니다. 이 경우 제품과 배송 서비스간에 API 호출을해야합니다. 배송 서비스는 제품이 특정 위치로 배송 가능한지 여부를 확인하기 위해 제품 서비스에 요청합니다. 배송 서비스는 제품 및 위치의 식별자 (이름, ID 등)로 제품 서비스를 요청합니다. 이러한 식별자는 최종 사용자로부터 가져 오거나 마이크로 서비스간에 공유됩니다. 여기에서는 마이크로 서비스의 데이터베이스가 다르기 때문에 이러한 마이크로 서비스의 데이터간에 외래 키를 정의 할 수 없습니다.

API 호출은 구현하기가 더 쉬울 수 있지만이 옵션에서는 네트워크 비용이 더 높습니다. 또한 API 호출을 할 때 서비스가 덜 자율적입니다. 귀하의 예에서 제품 서비스가 다운되면 배달 서비스가 작업을 수행 할 수 없기 때문입니다. 비동기 메시징으로 데이터를 복제하는 경우 배달에 필요한 데이터는 배달 마이크로 서비스의 데이터베이스에 있습니다. 제품 서비스가 작동하지 않을 때 배송 할 수 있습니다.


2
좋은 대답입니다. API 호출을 사용하지만 다른 서비스의 데이터를 정렬하고 페이지 매김해야합니다. 그 사건에 대한 최선의 접근 방식을 알고 있습니까?
tranceholic

6
페이징 및 정렬과 관련된 매개 변수를 API에 추가해야합니다. 그런 다음 올바른 순서로 올바른 페이지를 얻는 책임은 API 소비자에게 있습니다. GraphQL과 같은 API를 정의하는 데 사용되는 몇 가지 기술이 있습니다. 내가 아는 한 이러한 기술에는 이미 정렬 및 페이지 매김 기능이 있습니다. 이러한 종류의 기술을 사용하지 않는 경우 클라이언트에서 매개 변수를 가져 와서 페이지별로 정렬 된 데이터를 반환하는 데 사용하면됩니다.
Ali Sağlam

1
참으로 큰 대답!
TS

2
하지만 외래 키를 유지합니까? 예 : 모든 블로그 게시물에는 많은 댓글이 있습니다. Monolith에는 블로그 게시물에 대한 외래 키가있는 주석 테이블이 있습니다. 그러나 마이크로 서비스에서는 두 가지 서비스가 있습니다. 서비스 1 : 이러한 테이블 필드 (PostID, Name, Content)를 사용하여 Microservie 게시 서비스 2 : 이러한 테이블 필드 (CommentID, PostID, Cpmment)를 사용하여 Microservie를 설명합니다. 질문은 서비스 2 (Comments Microservice)에 "PostID"가 필요합니까? 어떤 댓글이 어떤 게시물에 속하는지 알아야하므로 대답은 '예'라고 생각합니다. 내 이해가 맞습니까?
rakesh mehra

1
시스템을 마이크로 서비스로 나누는 방법은 완전히 다른 이야기이지만, post 및 comment와 같은 2 개의 마이크로 서비스를 만들기로 결정한 경우 각 댓글이 게시물에 속하므로 댓글 마이크로 서비스에 대한 게시물 식별자가 필요합니다. 그러나 이러한 테이블간에 FK를 정의해야한다는 의미는 아닙니다. FK는 데이터 무결성과 일관성을 보장하는 데 도움이되는 RDBMS 세계의 유일한 제약 조건입니다. 이러한 마이크로 서비스의 데이터를 별도의 스키마에 보관하면 FK를 정의 할 수 없거나 FK를 적용 할 수없는 nosql db (댓글 마이크로 서비스에 적합 함)에 데이터를 보관할 수도 있습니다.
Ali Sağlam

24

커플 링을 줄이기 위해 코드를 배포 할 때 리소스 공유를 피하고 싶고 데이터는 공유를 피하려는 리소스입니다.

또 다른 요점은 시스템의 한 구성 요소 만 데이터를 소유하고 (상태 변경 작업의 경우), 다른 구성 요소는 읽을 수 있지만 쓸 수는 없으며, 데이터 복사본을 가질 수 있거나 최신 상태를 가져 오는 데 사용할 수있는 뷰 모델을 공유 할 수 있습니다. 개체의.

참조 무결성을 도입하면 커플 링이 다시 도입됩니다. 대신 기본 키에 Guids와 같은 것을 사용하고 싶을 것입니다. 객체 생성자가 생성하고 나머지는 최종 일관성을 관리하는 것입니다.

자세한 내용은 NDC Oslo 에서 Udi Dahan의 강연을 참조하세요.

도움이 되었기를 바랍니다


2
우디 다한의 이야기에 대한 링크는 매우 흥미 롭다
Comencau

3

첫 번째 솔루션 : API 구성

 Implement a query by defining an API Composer, which invoking the
 services that own the data and performs an in-memory join of the
 results

여기에 이미지 설명 입력

두 번째 솔루션 : CQRS

Define a view database, which is a read-only replica that is designed to support that 
query. The application keeps the replica up to data by subscribing to Domain events 
published by the service that own the data.

여기에 이미지 설명 입력


1

이 답변에 대한 2020 업데이트는 Debezium과 같은 변경 데이터 캡처 도구를 사용하는 것입니다. Debezium은 데이터베이스 테이블의 변경 사항을 모니터링하고이를 Kafka / Pulsar (기타 파이프)로 스트리밍하면 구독자가 변경 사항을 캡처하고 동기화 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.