강의

멘토링

커뮤니티

Inflearn Community Q&A

maro151021016132's profile image
maro151021016132

asked

Distributed Transaction Patterns from an MSA Perspective, Explained by a Kakao Interviewer

The first independent Choreography success and failure of the SAGA pattern and considerations accordingly

강의 11 질문

Resolved

Written on

·

43

1

강의의 시퀀스 다이어그램을 보았을 때, 2가지 정도 질문 드립니다.

 

1) stateless 요청에서 상태값의 전달 관련

  • 일반적으로 웹과 같이 stateless 한 서비스를 고려했을 때,

    비동기 처리로 인해 주문서비스가 고객의 주문요청에 대해 (이후의 수행작업과 상관없이) 즉시 리턴하게 되는 것이 예상되는데요. (위 그림에서는 동기적인 flow 로 주문완료 응답을 end point 유저에게 전달하는 것으로 보이긴 합니다만)

     

주문 완료 페이지에서 주문한 상품 정보나 결제 수단의 상태값 전/후 를 보여주는건 어떤 식으로 동작하게 될까요?

 

가령, 실물 상품이 아닌 연속선상의 사이버 재화(ex: 네이버포인트 등)를 지급해야하는 입장에서

주문 이전의 재화 정보와 주문 요청 후(최종적으로 트랜잭션 완료된 후의) 증/감 재화 정보를 유저에게 보여주어야 할 수도 있는데,

뒷단의 비동기 작업(이벤트 subscribe)을 수행하는 스레드랑 최초 주문 요청을 받는 요청스레드가 다른 부분에서 고려해야할 것이 더 있을 것 같은데요.

 

얼핏 생각했을 때는, 사용자에게 즉시 내려주는 응답 페이지는 PENDING 에 해당하는 페이지 UI 로 (ex: 결제 진행중... 표시) 전달하고, 사용자 PENDING 페이지(클라이언트)에서 몇초 단위의 주기적인 서버 요청 등으로 완료 이벤트를 조회 하도록 처리하여 완료페이지로 리다이렉션 처리되는 방식이 될까요?

이 때, 중간 상태값은 별도 캐시서버등에 저장을 해야 할 것이고요. (리다이렉션 되는 완료페이지와 PENDING 페이지의 state가 또 다르므로)


2) 메시지 브로커(카프카) 를 쓸 때 고려사항

  • 주제랑 좀 벗어난 걸 수는 있는데요, 보통 메시지 발행의 정확성을 위해 CDC (Change Data Capture) 를 설정하는 것이 일반적인 방식으로 알고 있습니다.

  • 다만, 현재 서비스중인 DB 의 설정이나 부하 이슈로 CDC 를 쓰지 못하는 경우에는 어떤 방식으로 처리가능할지가 궁금합니다.

javaspringmysqlspring-bootmsa

Answer 2

1

Hong님의 프로필 이미지
Hong
Instructor

1) stateless 요청에서 상태값의 전달 관련

해당 질문에 대해서는 우선적으로 고민하고 말씀해주신 부분이 일단 맞습니다. 가장 일반적으로 사용 할 수 있는 패턴이에요.

 

이떄 중요한거는 ID를 기반으로 값을 다시 요청하거나 주기적으로 요청을 함으로써 상태를 계속해서 확인하는거죠. 이 기반을 구현할떄는 세가지 방식이 있을 겁니다.

 

첫번쨰는 Polling 입니다. 가장 단순한 형태죠. 예를들어서 1~2초마다 계속 서버에 값을 요청하는 형태가 될 겁니다. 그걸로 Clinet의 State 변경을 인지하는거고요.

 

두번쨰는 Socket이 있을꺼에요. 가장 효율적인 형태지만, 인프라 복잡도나 상태 관리가 어려울수는 있죠.

 

세번쨰로는 Long Polling이 존재할겁니다. 사실상 Polling과 동일하죠.

 

이떄 중간 상태값은 음... 어떤 관점을 보시냐에 따라 다르기는 한데, 말씀해주신 부분처럼 Redis나 DB에 저장을 하는것이 가장 안전합니다. 근데 일부 유실되어도 무방한 트래픽이라면 그냥 메모리에서 관리해도 괜찮다고 생각을 하는편이고요.

 

2) 메시지 브로커(카프카) 를 쓸 때 고려사항

CDC라는 개념도 알고 계시다니 대단하시네요 ㅎㅎ 우선 메시지 발행의 정확성을 위해서 CDC를 설정한다는 것이 무슨 뜻인지 모르겠는데, DB에 대한 상태 변경을 인지하고 이벤트화를 하는 기능을 CDC라고 합니다. 레플리카 개념을 따라가는거죠.

 

근데 CDC를 사용하지 못한다면.... Transactional Outbox 패턴을 따라가시면 어떨까싶어요.

간단하게 표현하자면 이런 패턴이라고 봐주시면 됩니다.

 

[Application]
   |
   | BEGIN TX
   |   - 비즈니스 데이터 변경
   |   - outbox 테이블 insert
   | COMMIT
   v
[DB]

 

이 상황에서 Outbox Publisher라는 역할을 따로 두고, 주기적으로 outbox 테이블을 polling하고 Kafka에 이벤트를 발행하고 그 이후에 처리하였다고 outbox 테이블의 상태를 변경하는거죠

HW J님의 프로필 이미지
HW J
Questioner

강의 듣다가 급하게 쓰느라 개념적으로 불완전한 질문을 하게 된 것 같은데, 바로잡아주셔서 감사합니다.

 

질문의 취지는 Transaction log tailing Pattern (outbox pattern + CDC) 를 기준으로 설계를 고려했다가 (DB 부하등의 이슈로) CDC 가 불가능할 때, outbox pattern 를 어떤식으로 구현할 대안이 있을지 궁금해서 질문을 드렸습니다.

 

답변 주신 것의 요점은 결국 이벤트의 변경(추가)를 탐지할 다른 주체 (Outbox Publisher) 를 두고 일종의 Polling Publisher Pattern 을 구현하는 방안으로 이해했습니다.

log tailing 방식보다 polling 방식이 더 부하가 적을지, 효율적인지는 미지수지만요.

 

보통 polling publisher 를 구현할 때, 개별 마이크로 서비스 내에서 자체적으로 구현을 하는지, polling 전담 서비스를 따로 구축하는지 추가로 궁금하여 질문 드립니다.

 

답변 감사합니다.

Hong님의 프로필 이미지
Hong
Instructor

현실적으로 일반적인 상황이라면 각 MSA 내부에 구현을 하는게 더 편합니다.

 

왜냐하면, 일단 단순하기 떄문이에요. 별도 서비스를 구축 할 정도의 개념이 아니라고 생각이 들기 떄문이고 같은 서비스 내에서 호출이 가능하다는게 사실상 네트워크 통신을 배제 할 수 있는거라서 지연시간이 굉장히 낮아지는거죠.

 

근데 물론 서비스 수가 많고 관리가 힘들때에는 전담 서비스를 구축하셔야겠죠. 그래야 중복된 코드도 줄어들고, 통합적인 모니터링도 가능할겁니다.

 

그래서 사실 상황에 따라 너무나도 달라서 그 상황이나 추구하시는 방향에 맞춰서 구현을 하시는게 맞는거 같아요.

0

안녕하세요, 인프런 AI 인턴입니다. HW J님.

질문 주신 내용은 MSA 아키텍처에서의 상태 관리와 메시지 브로커 활용에 대한 중요한 두 가지 질문입니다. 각각에 대해 자세히 설명드리고 관련 있는 기존 논의를 소개하겠습니다.

1) Stateless 요청에서 상태값의 전달 관련

주문 서비스에서 비동기적으로 처리가 진행되는 경우, 상태값 전달 및 처리 후 상태에 대한 사용자 피드백은 중요한 문제입니다. 일반적으로 다음과 같은 방식으로 구현할 수 있습니다:

  • 초기 응답 처리: 주문 요청을 받은 후 첫 응답은 PENDING 상태를 반환합니다. 이는 클라이언트가 주문이 접수되었음을 알 수 있도록 하는 것입니다.

  • 상태 추적 및 최종 응답: 이후 비동기적으로 진행되는 트랜잭션은 웹소켓, 폴링, 이벤트 푸싱 방식 중 하나를 통해 클라이언트와 상호작용합니다. 폴링의 경우 클라이언트가 주기적으로 서버에 상태를 조회하여 완료 시 리다이렉트하면 됩니다.

  • 상태 저장소: 중간 상태와 최종 상태는 Redis 같은 인메모리 데이터 저장소에 저장하여 빠르게 접근할 수 있도록 합니다. 이는 주문 프로세스가 길어질 수 있는 경우에도 안정적으로 상태를 관리할 수 있도록 합니다.

2) 메시지 브로커(카프카)를 쓸 때 고려사항

CDC를 사용하지 않는 경우, 데이터베이스의 변경 사항을 메시지 브로커로 직접 발행하는 방식이 필요합니다. 다음과 같은 방법을 고려할 수 있습니다:

  • 트랜잭션 아웃박스 패턴: 서비스의 트랜잭션 내에서 이벤트 로그를 생성하고, 이 로그를 비동기적으로 소비하여 메시지 브로커에 발행합니다. 이로 인해 데이터의 일관성을 유지하면서도 시스템의 복잡성을 줄일 수 있습니다.

  • 앱 레벨의 직접 발행: 애플리케이션 레벨에서 DB 변경과 함께 직접 카프카에 메시지를 발행하는 방식을 사용합니다. 이런 경우, 다시 한번 데이터의 일관성을 고려해야 하며, 구현 시 잠재적인 트랜잭션 관리 어려움이 있을 수 있다는 점에 유의해야 합니다.

유사한 주제를 다룬 기존 답변 링크도 참고해 보세요:

이 링크들은 MSA 아키텍처에서의 트랜잭션 관리와 이벤트 기반 메시지 처리에 대해 유용한 인사이트를 제공할 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

maro151021016132's profile image
maro151021016132

asked

Ask a question