예제 소스 코드
이번 블로그에 사용되는 코드는 아래 링크 통해 확인 할 수 있습니다.
https://github.com/syh8088/MSA_project/tree/main/paymentMsa
MSA Data Query 문제
MSA
경우는 각 서비스에 해당되는 데이터베이스에 이용되고 있습니다. 그래서 특정 서비스가 다른 데이터베이스에 접근 하는것을 지양해야 합니다.
주문 서비스를 통해 결제된 주문 내역과 고객이 주문한 상품에 해당되는 Seller 의 Wallet 데이터도 조합해서 조회 하고 싶을때는 주문 서비스 통해 조회한 주문 데이터를 기반으로
정산 서비스에 조회된 Waller 데이터를 조합해서 client 에게 전달 하게 됩니다.
모놀리스
에서는 order 테이블 하고 Wallet 테이블를 JOIN 해서 간단하게 해결 할 수 있었던 것이 MSA
에서는 조합하기 위해서는 각각의 해당 되는 서비스에 호출해서 가져온 데이터를 조합 할 수밖에 업습니다.
어느정도 단순 쿼리 통해 각각 조회해서 가져온 데이터를 조합하면 되겠지만 요구사항이 “특정 Seller 가 등록했던 상품별 총 판매된 금액” 을 원한다고 했을때 입니다.
해당 되는 Seller 를 조회 하게 되고 Seller 정보 바탕으로 등록된 상품 정보를 조회 할 것 입니다. 그 상품 데이터를 이용해 주문 서비스에 각각의 상품 별 결제된 금액을 가져오게 될 것 입니다.
이렇게 호출을 여러번 하게 될 경우 DB 서버에 부하가 생길수 있다는 점 입니다. 특히 대용량 데이터베이스 이라면 더욱 DB 서버에 부하가 생깁니다. 추가적으로 상품 서비스에서 서버 부하가 생기면
호출하는 입장인 Seller 서비스에서는 서킷브레이커
통해 이 문제를 부분적으로 해결 할 수 있습니다. (상품 데이터 조회를 못 하겠지만 고객 입장에서는 딜레이 되는 문제를 어느정도 해소 가능)
CQRS 패턴으로 이 문제를 해결해 보자
지금까지 문제점에 대해 알아보았습니다. 이를 CQRS 패턴
을 통해 문제를 해결하고자 합니다. CQRS 패턴
이란 Command(쓰기)
, Query(읽기)
분리 해서 관리 하는 패턴 입니다.
Query
하고 Command
를 격리해서 관리 하므로 단일 장애 지점(SPOF)
문제 해결 그리고 확장성 및 보안을 최대화 할 수 있는 장점이 있습니다.
그런데 앞서 이야기 한 부분 중에 모든 데이터는 해당되는 서비스에서만 조회 하도록 해야 한다는 점 입니다. 예를들어 Seller 조회 하는데 있어서 Seller 서비스가 아닌 Seller Query 서비스가 담당 하는 것에
의문이 있을 수 있습니다. 조회 담당 기능을 Seller Query 서비스가 담당하고 해당 데이터를 변동 시키는 주체는 기존 Seller 서비스에서 하면 문제가 없을 것 입니다.
다음 사진은 주문 서비스 전용 Query Service 인 Order_Query_service 를 새로 만들 예정입니다. 이 서비스는 query
전용 담당만 할 예정입니다.
처음에 고객이 주문 요청시 결제 요청이 발생되고 주문 서비스에서 결제 승인의 결과에 따른 결제 상태까지 업데이트 하게 된다면 정산 처리를 하기 위해 이벤트 메시지를 발행 하게 됩니다.
동시에 또 주문 Query Service 에게도 이벤트 메시지를 발행 하게 되는데요. 주문 Query Service 에 이벤트 메시지를 받게 되면 주문 서비스에서 주문한 상품에 소속된 Seller 별로 상품별 총 금액을 계산해서 Redis 에 저장 및 업데이트를 합니다.
이렇게 저장 까지 완료된다면 이후 Seller 가 order_query_service 로 해당 Seller 의 상품별 총 금액을 조회 할 수 있도록 합니다.
Copyright 201- syh8088. 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.