TIL/개발 칼럼

#7 타행 이체 개선기, 비관락 획득 후 외부 API 호출 최소화

김민석(갈레, 페퍼) 2023. 5. 24. 10:09
반응형

📌  문제 상황

<그림1. 즉시 이체 처리 순차 다이어그램>

1. 즉각 요청-응답 프로세스는 외부 서비스와의 connection을 유지한 채 비관 lock을 잡기에, lock으로 인한 다양한 이슈가 외부 서비스로 전파될 위험 존재(ex. deadlock 발생시 connection도 대기)
2. 즉각 요청-응답 프로세스는 타행 이체(은행A→은행B 이체)를 2개의 API(이체 입금 요청 API, 이체 입금 완료 응답 API)로 구현하자는 은행 간 약속(프로토콜)을 무시하는 방법임.


📌 접근 방법과 해결과정

원인 분석

<그림2. 이체 입금 요청 비동기 처리 순차 다이어그램>

- 그림2 즉, 이체 입금 요청을 비동기로 처리하는 구조의 문제점 재파악.
- 입금을 위해 비관 lock을 잡고 Network I/O를 하는 것이 가장 큰 문제라고 파악.
- 특히 타행(이체 입금 역할)은 당행(이체 출금 역할)의 이체 내역(완료) 변경 로직 실행까지 기다려야 하는 책임 존재.

측정

<그림3. Elastic stack으로 확인한 병목 구간. 비관 lock>

- 비관 lock을 오래 잡는 것이 문제.
- Network I/O 호출 횟수를 줄이면 비관 lock 잡는 시간을 줄일 수 있음.

해결 방법

<그림4. 이체 입금 완료 응답을 아웃박스 패턴으로 처리>

- 비관락을 잡고 Network I/O 하는 시간을 줄이기 위해 ‘이체 입금 완료 응답 API’ 호출을 다른 트랜잭션에서 실행.
    - 그림2에선 타행(이체 입금 역할)이 당행(이체 출금 역할)의 이체 입금 완료 응답 API 처리까지 기다려야했음. 또한 당행이 이체 내역(완료) 변경 이외에 다른 Network I/O를 실행하면 이 마저도 기다려야 하는 상황임.
- ‘이체 입금 완료 응답 API’ 호출은 입금 로직의 핵심 이벤트 중 하나임. 서버 다운 상황에서도 실행이 보장돼야함. 이에 아웃박스 이벤트를 사용(이체 입금 이벤트를 DB에 적재).


📌 결과

평가

- 즉각 요청-응답 방식을 ‘이체 입금 요청 API’에 적용하지 않아, 외부 서비스로 lock 이슈가 전파되는 것을 방지
- 타행 이체(은행A→은행B 이체)를 2개의 API(이체 입금 요청 API, 이체 입금 완료 응답 API)로 구현하자는 은행간 약속(프로토콜) 지킴.
- 분산 트랜잭션의 최종 데이터 일관성 확인 소요 시간 개선(평균 이체 출금-입금 시간 차) (33 -> 0.3s)

비고

<그림5. 비즈니스 핵심 로직 & 부가 로직 분리>

- 현재 로직은 한 서버가 비즈니스 핵심 로직과 부가 로직을 모두 실행중임.
- 비즈니스 핵심 로직을 담당하는 서버(은행 핵심 코어)와 부가 로직(외부 은행과 통신)으로 나눌 수 있음.

반응형