Home 메시지를 안전하게 전달하기 Transaction Outbox Pattern
Post
Cancel

메시지를 안전하게 전달하기 Transaction Outbox Pattern

결제 모듈에는 결제 결과를 각 서비스에 전달하는 기능이 있다.

현재 메시지는 동기식으로 결제 완료 후 1회 전달되며, 각 서비스에서 콜백 처리 불가가 되더라도 재시도 해주지 않는다.

[!info] PG사에서는 응답코드가 200이 아니면 결과 메시지를 재전송 해주고 있다.

카드 결제, 네이버페이 등 동기로 작동하는 기능은 1회 동기로 전달하는게 맞는 것 같지만
가상계좌 입금은 굳이 동기로 전달해줄 필요가 없어보인다.

1회 실패 후 재전송 해주지 않는 것도 문제로 보인다.

  • 일반적으로 PG사는 결제 완료 콜백 시 에러 코드를 응답하면 몇번의 재시도를 해준다.

현재 백엔드로 결과를 콜백해주고 프론트로 리다이렉트를 하게 되는데 프론트에서도 결과를 저장하고 있다.

  • 프로에는 멱등성있게 처리가 되어 있어서 2번 결과 통보해도 문제가 없다.

그렇다면 꼭 백엔드로 콜백을 동기로 해줄 필요가 있는가? 의문이 든다. 많은 PG사를 분석했을 때는 보통 백엔드로 결과를 주지않고 리다이렉트 형식으로 결과를 주고 처리하도록 한다.

외부와 통신을 하는 경우에 다양한 문제가 있을 수 있다.

  • 네트워크 이슈
  • 서버 이슈
  • 휴먼 이슈

메시지를 전달하다가 발생하는 문제들

그러면 재시도 하면 되잖아요.

트랜잭션 이후에 메시지 전송이 실패하면 재시도를 하면되지 않을까요? 요청을 재시도할 순 있지만 재시도하다가 서버가 다운되는 경우 메시지는 사라지게 된다.

메시지를 보내고 커밋하면요?

이렇게 메시지를 보내고 트랜잭션을 커밋한다면?
메시지 전송 성공 후 트랜잭션이 실패한다면 메시지를 받는 쪽과 불일치가 발생하게 된다.

이 때 등장하는 것이 있으니.

Transaction Outbox Pattern

보통 MSA환경에서 메시지를 안전하게 전달할 때 많이 사용하는 패턴이다. *Outbox : 발신 편지함

At-Least Once Delivery (적어도 한번 전달) 보장하기 위한 방법 메시지 발행에 시차가 생길 수 있지만 결과적 일관성(Eventual Consistency)을 유지할 수 있다.

해당 패턴으로 아래의 문제를 해결할 수 있다.

  1. 발행되어야 하는 메시지가 발행되지 않는다.
  2. 발행되지 말아야 하는 메시지가 발행된다.

필요사항
  1. Outbox Table
  2. Outbox Table Polling Process
    1. Polling Publisher
    2. Transaction Log Tailing
      1. Debezium
  3. Message Broker (Kafka, SQS, HTTP)

메시지 순서

메시지 마다 시퀀셜한 아이디를 부여해서, Polling Process에서 시퀀셜 아이디로 정렬 후 이벤트를 발행하면 메시지 순서를 맞출 수 있다.

주의사항
  • Outbox에 메시지를 저장하는 행위도 서비스 로직으로 본다.
    • 메시지를 저장하다가 실패하면 결제 요청까지 롤백되고 실패로 봐야하는가 에 대한 답변
  • 메시지의 양이 많은 경우 Outbox테이블이 빠르게 커질 수 있기 때문에 일정 기간 이후에 삭제하는 프로세스를 만들어야할 수 도 있다.

관련

This post is licensed under CC BY 4.0 by the author.

NAT Gateway Connection Rest 이슈 분석

배치 처리 성능 최적화 if kakao 2022