ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 토스 - SLASH 22 - 토스뱅크의 완전히 새로운 대출 시스템
    세미나, 영상 요약정리 2023. 9. 15. 00:01

    https://www.youtube.com/watch?v=SLamxuykpnw 

    토스뱅크에서 대출서버 Server Developer 민재슬님의 발표를 듣고 정리해보고자 합니다.

     

    전통 금융 회사의 아키텍처

    전통 금융 회사 아키텍처

    전통금융회사는 비즈니스 로직이 계정계라 불리는 모놀리식 코어뱅킹에서 구현됩니다.

    채널계라 불리는 서비스 서버의 역할을 사용자와 연계하여 제품을 사용하는 게 필요한 요청과 응답을 코어 뱅킹 시스템의 전문 규격에 맞추어 변환하고 전달하는데 중점을 두고 있습니다.

     

    모놀리식서버의 단점으로 신규 제품 개발에 더 많은 시간이 소요되게 됩니다 (분석을 위해..)

     

    토스 뱅크의 아키텍처

    토스 뱅크의 아키텍처

    마이크로서비스의 장점을 가져와서  서비스서버와 코어뱅킹서버를 각각 독립된 API 서비스로 정의하여 독립된 서비스가 비즈니스 로직을 처리할 수 있도록 하였습니다.

     

    MSA로 늘어나는 스키마 관리포인트 해결방법

    독립된 서비스마다 독립된 스키마를 가지고 필요에 따라 API로 데이터를 요청하며 비즈니스를 처리합니다.

     

    사용자 서버, 약관 서버, 상품 서버, 대출 서버마다 독립된 스키마를 가지기 때문에 복잡도가 올라가게 됩니다.

    토스뱅크에서는 어떤 방식으로 스키마 관리를 진행할까?

    • HIBERNATE, Flyway를 통해서 관리한다 (단, 운영 환경에서는 적용하지 않는다)
    • hbm2ddl.auto = validate 옵션을 통해 현재 만들어진 스키마와 JPA에서 생성된 Entity가 일치하는지확인합니다. (data class entity와 스키마가 달라지면 오류가 발생한다.)  -> 사내에서도 dev에만 적용했는데 beta, prod까지 도입해 보면 어떨까?
    • integration test를 통해서 레파지토리에 대한 mocking없이 직접 연계된 DB 테스트를 수행할 수 있습니다.

     

    대출 시스템에 필요한 연계기관들에 가능한 만큼만 호출하기

    KBC, NICE, 신용정보와 같은 대외기관과 통신구조도 새롭게 디자인하였습니다.

     

    대출하는 절차는 다음과 같습니다.

    • 신용정보 조회(허가받은 기관과의 통신 - KCB, NICE 등)
    • 현재 고객의 대출정보, 필요한 부가정보 (대외기관)

    하지만 연계된 기관들이 늘어나면 응답시간이 지연됨니다.

    기존 금융권에서는 여러 기관을 동시에 호출하는 비동기 방법으로 해결합니다.

    하지만 이때 대외기관이 처리하지 못하는 양보다 더 많은 트래픽을 흘리게 되면 대외기관의 시스템이 마비됩니다.

    심지어 대출의 특성상 대외기관의 협업 없이는 서비스를 제공할 수 없습니다.

     

    토스뱅크는 구축초기부터 파이프라인과 유량제어 시스템을 도입하였습니다.

    Kafka를 통해 고객의 요청은 파이프라인에 도달되고 Consumer에는 메시지를 처리할 수 있는 독립된 Thread Pool을 설정하고 대외기간의 상태에 따라 상이하며, 대외기관이 알려준 기본성능으로 세팅되어 있습니다.

     

    코루틴의 Fixed ThreadPool을 활용하여 각기 다른 사이즈의 스레드 풀을 array로 선언하여 필요에 따라 동적으로 선택가능하도록 하였습니다.

    이런 파이프라인을 각 기관마다 다르게 가져갑니다.

     

    하지만 여전히 문제는 존재합니다.

    • MAX TPS에 도달하고 신규요청이 계속 오면, 고객이 대출을 실행하기까지 늦은 응답시간이 소요될 수 있다.
    • 대외기관에 장애가 발생할 수 있다.

     

    유량 제어 시스템

    일반적인 서킷의 동작방식은 API 실패율로 측정하여 서킷을 open 하거나 half-open을 수행합니다.

    하지만 대출 시에는 여러 단계를 거쳐야 하며, 중간 단계의 서킷과 앞단계의 서킷이 서로 연동되어 동작하게 하여 사용자가 불필요한 과정을 거치지 않도록 수행하였습니다.

     

    이때 이를 위해서는 각 단계별 정확한 통계치를 가져야 합니다.

    스레드의 불필요한 점유 없이 Coroutine과 Web Client, Redis를 활용하여 non-blocking 지표 수집을 구현하였습니다.

    IO기반의 작업이며 request Thread를 사용하지 않아 서비스에 영향도를 줄인 것입니다.

     

    서버는 파이프라인 적재 직전 이벤트의 시작 시간을 Redis에 적재하고, 응답 완료 시각, 성공 실패 여부를 기록합니다.

    이 데이터는 Redis에서 MySQL로 1분 단위의 지표를 적재합니다.

    이 정보로 대외기관의 TPS와 실패율을 볼 수 있습니다.

     

    약속된 TPS 또는 실패율이 증가하게 된다면 dynamic pool 사이즈를 조절합니다.

    하나 이로써 해결되지 않는다면 앱 스크래핑 가능한 인증서를 가지고 있다면 마이데이터의 서킷을 open 처리하여 앱 스크래핑으로 전환합니다.

     

    꼭 필요한 시스템에서 장애가 발생한다면?

    보완 가능한 대외기관이 가능하지 않다면..  대출상품 전체의 진입서켓도 연동하여 open 하여 진입 자체를 차단하게 됩니다.

    적절한 TPS로 요청을 보내기 때문에 대외기관에 문제가 발생할 일은 거의 발생하지 않으며, 보통 대외기관에 문제가 발생했을 때 사용하게 됩니다.

     

    추가적으로 대기열 시스템을 도입하여, 입장티켓을 발급받아야 진입할 수 있도록 구현하였습니다.

    일정한 주기에 따라 일정한 수만 진입되기 때문에 시스템에 들어오는 사용자의 수를 조절할 수 있습니다.

    이때 고객이 심사를 받는 임계시간이 넘어가게 되면 대기열 시스템이 가동됩니다.

    댓글

Designed by Tistory.