📚 Study

[Toss SLASH22] Day 2 - 왜 은행은 무한스크롤이 안되나요

date
Jun 25, 2023
slug
toss-slash22-day3-angkstmzmfhf
author
status
Public
category
📚 Study
tags
Toss
Conference
DB
summary
Kafka를 사용한 채널계-계정계 송금 내역 동기화 분투기
type
Post
thumbnail
스크린샷 2023-07-05 오후 8.09.11.png
notion image

왜 은행은 무한스크롤이 안되나요

토스뱅크 Server Developer 이응준 님
은행 앱에서 한 달 전의 통장 거래내역을 보기 위해서는 스크롤을 이용할 수 없습니다. 귀찮더라도 조회 기간을 입력해야 하죠. 사실 이건 모든 은행의 서버 아키텍처와 관련된 문제이기도 합니다. 그렇다면 토스뱅크는 이 문제를 어떻게 해결했을까요?
 

은행 서비스는 송금 내역을 보기 위해선 유저가 조회 기간을 직접 변경해야 한다

이는 은행 시스템 구조와 관련이 있음
은행 시스템은 은행앱 ↔ 채널계 ↔ 계정계 로 분리되어 있음
  • 계정계 : 실제로 유저의 돈을 다루며, 원본 데이터가 저장되는 영역
    • 따라서 장애나 오류가 발생하면 치명적이기 때문에 아주 높은 신뢰도가 요구됨
  • 채널계 : 유저의 요청을 직접 받아 처리하는 영역
    • 돈을 직접 다루지는 않고, 이 요청을 계정계로 전달
 

토스뱅크 시스템의 구조

채널계
  • Kubernetes 클러스터 위에 구축된 도메인별로 분리된 복수개의 서버 애플리케이션으로 구성
  • DB서버 역시 여러 개로 구성
  • 네트워크 구조가 복잡하고 DB가 여러 개로 나뉘어 있기 때문에 경우에 따라 트랜잭션 처리가 어려운 경우가 있음
  • 그러나 특정 서버에 부하가 몰리면 그것만 스케일아웃 할 수 있고, DB 부하가 커지면 DB를 분리하는 선택을 할 수 있기 때문에 큰 트래픽을 다루는데 유리함
계정계
  • 하나의 서버 애플리케이션으로 구성, 데이터베이스 서버도 1개
  • 서버가 하나이기 때문에 네트워크 구조가 단순하고, DB가 하나이기 때문에 트랜잭션 처리가 유리함
  • 특정 서버만 스케일아웃하거나 DB를 분리하는 등의 선택을 할 수 없기 때문에 급증하는 트래픽을 그대로 소화하기에 다소 불리
  • 오류 없이 동작하는 것이 매우 중요하기 때문에 성능을 희생하더라도 이런 아키텍처를 택하게 됨
notion image
 

일반적인 은행 앱에서 고객이 거래 내역을 조회하는 경우를 생각해보자

거래 내역은 매우 핵심적인 기록이기 때문에 계정계에서 관리함
따라서 채널계는 고객의 거래 내역 조회 요청을 받아 계정계에 전달하고, 그 결과를 다시 앱으로 전달함
계정계는 성능보다 신뢰도가 우선이기 때문에 광범위한 거래내역 조회를 빠른 응답시간에 적은 부하로 제공해주기는 어려움
따라서 그런 요청을 최소화하기 위해 UI에서 디폴트 조회범위를 수개월 범위로 한정하는 것이 현명한 선택
 

그러나 토스뱅크에는 기간 설정 기능이 없고 무한 스크롤이 제공된다

토스뱅크는 거래내역 조회를 할 때마다 계정계의 코어뱅킹 서버에 요청을 보내지 않고, 채널계에 있는 송금 서버가 거래내역을 직접 반환한다.
이렇게 동작하려면 채널계의 송금 서버가 항상 코어뱅킹 서버와 거래내역을 정확하게 동기화하는 문제를 해결해야 한다. 조금만 어긋나면 거래내역이 누락되는 문제가 생기면서 은행의 신뢰성에 큰 타격을 입을 수 있다.
그렇다고 너무 코어뱅킹 서버와 자주 동기화를 시도하면, 코어뱅킹 서버의 부하가 너무 커져서 장애가 발생할 수도 있음
어떻게 해야 할까?
 

시도 - 유저가 이체를 실행할 때마다 이체 내역을 송금 서버의 DB에 저장하기

그러면 송금 내역이 전부 송금 DB에 잘 저장될테니 그걸로 거래내역 조회를 하면 되지 않을까?
이렇게 하면, 다른 은행앱에서 토스뱅크에 입금한 것은 조회가 되지 않음
따라서 이런 경우엔 코어뱅킹 서버가 송금 서버에게 입금이 되었다는 사실을 알려주어야 함
 

타행 입금 누락 문제 해결 → Kafka

토스뱅크에서는 Kafka를 이용함
코어뱅킹 서버가 Kafka 토픽에 메시지를 프로듀싱하고, 송금 서버가 컨슘하여 송금 DB에 저장함
notion image
하지만 이것은 모든 것이 잘 이상적으로 돌아가는 상황에서만 정상 동작함
예외 상황에 대한 대처가 필요함!
 

송금 이력 누락 문제 해결 → Kafka

예를 들어, 송금 실행 도중 코어뱅킹 서버의 응답이 늦어져서 타임아웃으로 송금 서버가 응답을 받지 못한다면 거래내역을 DB에 저장하지 못하고, 유저는 송금이 성공했더라도 해당 거래내역을 볼 수 없게 됨
이 문제 또한 Kafka로 해결 가능
송금 API 실행 중 타임아웃이 발생했더라도 송금이 완료되었을 때 코어뱅킹 서버가 Kafka 토픽을 통해 송금 서버에게 이체 실행 결과를 알려준다면 송금 서버가 거래내역을 송금 DB에 저장하고 유저에게 제공해줄 수 있음
유저는 송금 직후엔 타임아웃으로 인한 에러를 만나겠지만, 결국 최종적으로 송금이 완료되고 나면 거래내역에 송금건이 조회될 것임
notion image
하지만 여전히 큰 문제의 가능성이 남아 있음
 

중복 송금 문제 → DB에 임시저장

타임아웃으로 인해 에러를 만난 유저가 송금이 실패한 줄 알고 다시 중복해서 송금을 할 가능성
이 문제를 막기 위해 송금 요청이 들어오면 송금 서버는 코어뱅킹 서버에 송금 요청을 보내기 전에 우선 송금 요청을 DB에 저장함
그리고 완료되지 않은 송금 요청이 있는 유저가 다시 송금을 요청하면 거절함
나중에 송금이 완료되어 송금 서버가 송금 이력을 저장까지 끝내고 나면 그때부터 새로운 송금 요청을 수락하게 됨
notion image
하지만 이 경우 또 다른 문제가 발생한다… 송금이 영원히 지연될 수 있는 문제
 

송금이 계속 지연되는 문제 → 오래된 지연 송금 실패 처리

만약 네트워크 문제로 인해 송금 서버가 코어뱅킹 서버로 보낸 송금 요청이 코어뱅킹 서버에 도달하지도 못한다면 송금은 실행되지 않을 것이고, 그렇게 되면 송금 요청은 여전히 진행 중인 상태로 송금 DB에 남게 됨
그렇게 되면 유저는 영원히 송금을 할 수 없게 됨
이 문제를 피하기 위해 송금 서버는 주기적으로 코어뱅킹 서버에게 송금 요청의 상태를 확인함
송금 요청이 코어뱅킹 서버에 도달하지도 못했으므로 코어뱅킹 서버는 해당 송금 건에 대해 ‘없음’이라고 응답
그러면 송금 서버는 해당 송금 요청이 실패 되었다고 처리함
이제 지연된 송금이 없으므로 유저는 계속해서 송금을 요청할 수 있음
notion image
그런데… 이 처리가 잘못되어 성공을 실패로 처리해버릴 가능성이 있다면?
 

송금에 성공했는데 응답지연으로 인해 실패로 처리한다면? → 타임아웃 약속

뒤늦게 송금 요청이 코어뱅킹 서버에 도달해서 성공적으로 송금이 성공하는 경우
코어뱅킹 서버는 송금 요청이 없었다고 응답하여 송금 서버는 이 요청을 실패로 처리함
⇒ 타임아웃 시간을 약속하고, 그보다 오래된 요청은 거절
타임아웃 시간이 지났는데 코어 뱅킹 서버로부터 송금 완료 메시지가 오지 않으면 상태 조회를 요청한 후 없음이 오면 실패로 처리, 코어 뱅킹 서버 또한 타임아웃이 지난 요청이 도착하면 처리하지 않고 거절
notion image
 

송금 이력 저장 실패

예를 들어, 순간적인 DB 장애로 저장에 실패한다면?
이런 경우 송금 서버는 잠시 후에 송금 완료 메시지를 다시 컨슘하고 이력을 저장함
그런데도 불구하고 여전히 실패한다면? → 몇 번을 재시도해도 실패하는 상황으로 간주하고 재시도하지 않음
대신 컨슈머 데드 레터(Consumer DeadLetter)라는 Kafka 토픽에 실패한 메시지를 저장하고, 개발자가 실패하는 원인을 확인하여 문제를 해소한 뒤, 해당 토픽을 다시 컨슘하여 송금 이력을 저장하게 됨
notion image
 

송금 이력 누락 문제

(이어서…)
 

그럼에도 불구하고 어떠한 문제로 인해 동기화가 안되는 경우

유저가 직접 동기화할 수 있는 버튼 마련
notion image
 

정리

  1. 빠른 거래내역 조회를 위해 채널계에 거래내역을 적재
  1. 채널계에서 적재된 거래내역을 이요해 중복 송금 방지
  1. Kafka 메시지를 이용해 계정계와 채널계 사이의 거래내역을 동기화
  1. 만약의 경우를 대비하여 수동 동기화 제공
 
유저 편의를 위해 기존 틀을 깨고 새로운 방법을 연구할 수 있다는 것이 토스뱅크만이 할 수 있는 장점!