📌 문제 상황
<그림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. 비즈니스 핵심 로직 & 부가 로직 분리>
- 현재 로직은 한 서버가 비즈니스 핵심 로직과 부가 로직을 모두 실행중임.
- 비즈니스 핵심 로직을 담당하는 서버(은행 핵심 코어)와 부가 로직(외부 은행과 통신)으로 나눌 수 있음.
'TIL > 개발 칼럼' 카테고리의 다른 글
TDD 관점에서 테스트란? 장단점은? (0) | 2023.07.25 |
---|---|
Resume 링크 (0) | 2023.04.23 |
#6 타행 이체 기능 성능 개선기, 속도(gap lock으로 인한 insert 병목 해결) (1) | 2023.04.20 |
#5 타행 이체 기능 성능 개선기, 속도(이체 입금 요청 API 처리 전략) (2) | 2023.04.08 |
#4 타행 이체 기능 성능 개선기, 속도(인프라 개선) (0) | 2023.04.08 |