[E-commerce App] 데이터 동기화 문제
하나의 마이크로 서비스를 하나 이상의 인스턴스에서 기동했을 때,
즉, 클라이언트의 요청이 여러 개가 들어왔을 때,
부하분산을 처리하기 위해서 여러 개의 인스턴스를 띄울 수 있다. (-> 랜덤 포트를 활용한 로드밸런싱)
개요
Multiple Order Service
지금까지 user-service
와 order-service
간 통신을 통해 데이터를 주고받는 예제를 살펴봤다.
그런데 위 사진과 같이, order-service
가 60001번 포트와 60002번 포트 두 개에서 기동되고 있다고 했을 때,
각각의 order-service
는 독립적인 db를 가지고 있기 때문에,
주문 데이터는 분산 저장되고, 이로 인해 동기화 문제가 발생할 수 있다.
어떤 경우에는 첫 번째 order-serivce
의 db에 데이터가 저장되고,
어떤 경우에는 두 번째 order-serivce
의 db에 데이터가 저장될 수 있다.
따라서 user-service
에서 사용자의 주문 내역을 가져올 때에도,
어떤 경우에는 데이터를 하나만 가져오고, 어떤 경우에는 두 개를 가져올 것이다.
이러한 문제를 어떻게 해결할 수 있을까?
해결책
하나의 Database 사용
두 개의 order-service
인스턴스에서 하나의 db를 사용하면 해결할 수 있을 것이다.
하지만, 물리적으로 떨어져있는 두 개의 인스턴스에서 하나의 db에 저장하기 위해서는 동시성 혹은 transaction 문제를 잘 해결해야 할 것이다.
Database 간의 동기화 (Message Queuing Server 사용)
다른 방법으로는, 각각의 인스턴스가 가지고 있는 db에 있는 데이터들을 동기화하여 해결할 수 있을 것이다.
동기화는 Kafka나 RabbitMQ와 같은 Message Queuing Server를 이용해 할 수 있다.
그러면 어떻게 동기화 할 수 있을까?
한 쪽의 db에 변경이 있을 때, 그 값을 Message Queuing Server에 전달할 것이다.
그럼 다른 한 쪽의 db는 Message Queuing Server에 “변경된 데이터가 있으면 알려줘”하고 구독을 하고 있다가,
변경된 데이터가 있을 때, 그 데이터를 가져와 자신의 데이터베이스를 업데이트 할 수 있다.
하나의 Database 사용 + Message Queuing Server 사용
세 번째로, Message Queuing Server 사용하고 db도 하나를 사용할 수 있다.
첫 번째 db에서 발생한 데이터와 두 번째 db에서 발생한 데이터를 우선 Message Queuing Server에 전달한다.
(Message Queuing Server는 메시지 전달에 특화되어있는 시스템이기 때문에,
아무리 많은 데이터가 들어와도 1초안에 수만건의 데이터를 처리할 수 있어 동시성 문제를 해결할 수 있다.)
그리고 Message Queuing Server에 전달된 데이터를 하나의 단일 db에 저장한다.
그럼 각각의 order-service
가 자신이 필요한 데이터를 단일 db에서 조회한다.
orser-service
터미널에서 mvn spring-boot:run
으로 order-service
를 하나 더 기동하자.
(랜덤포트로 기동될 것이기 때문에 포트 충돌의 문제는 없을 것이다.)
유레카 서버를 확인해보면, 아래와 같이 두 개의 order-service
가 기동되고 있음을 확인할 수 있다.
문제 확인
위에서 우려했던 것과 같이,
두 개의 order-service
를 기동한 뒤에 사용자 단건 조회를 했을 때,
매번 요청을 할 때마다 가져오는 db의 값이 다름을 확인할 수 있다.
💛 개인 공부 기록용 블로그입니다. 👻