전세대출에서 대외기관 신용정보를 조회하는 방법
토스뱅크는 기술로 은행산업의 변화를 만들어 내기 위해 끊임없는 도전을 이어왔어요. 출범 단 2년 반 만에 1,000만 은행이 될 수 있었던 것은 이러한 기술혁신을 위한 시도가 있었기 때문인데요. 지난 8월 9일 토스뱅크의 첫번째 테크 밋업 Tech.nic에서 토스뱅크가 다른 은행과는 다른 기술 환경을 갖추기까지의 과정, 마주한 문제를 임팩트 있게 해결해 나간 노하우를 소개했습니다. 토스뱅크만의 일하는 방식과 성공 방정식, 그리고 앞으로의 도전 방향성까지 "은행을 바꾸는 은행"이 되기 위한 토스뱅크만의 과정이 궁금하시다면 앞으로 Tech.nic에서 소개드릴 이야기에 집중해주세요!
토스뱅크에서 최근에 전세대출 상품을 개발하면서 기존 DevOn 프레임워크에서 벗어나 Spring과 Kotlin 환경에서 전환 작업을 진행했습니다. 다시 말하면 계정계 MDD(Model Driven Development)환경이 아니라 독립된 서버에서 운영할 수 있는 MSA 환경으로 개발했습니다.
기존 프로세스 중에서 여신 심사 프로세스를 전환했는데요. 이 프로세스 중에 대외기관을 통해 신용정보를 가져오는 기능의 운영이 가장 유연해진 것 같아 개선한 경험을 소개합니다.
기존 문제점
이번 MSA 전환 작업에서 코드와 개발 환경을 마이그레이션하면서 기존 시스템의 불편한 점도 많이 발견했는데요. 여기서 몇 가지 문제를 소개드릴게요.
먼저 기존 프로세스는 어떻게 구성되어 있을까요? 신용 정보 조회는 여신 프로세스에서 고객이 금융권에 들어와서 대출 가능 여부 및 한도를 결정하는 중요한 정보 중 하나인데요. 신용 정보 조회를 위해서 다양한 기관과 여러 서비스를 이용하고 있어요. 또 대외기관의 데이터는 실시간 비동기 방식으로 요청해서 받아와 활용하고 있었습니다.
아래 그림은 많은 금융기관에서 사용하고 있는 채널과 계정계 사이 통신 방식을 간략히 나타내고 있어요.
토스뱅크는 앱으로 신용조회가 진행하면, MCI(Multi Channel Integration)를 통해 계정계로 “신용정보를 조회해주세요”라는 요청을 보내요. 계정계는 해당 요청을 받아 FEP(Front End Processor) 서버를 이용해서 대외기관과 연계를 수행해요. 요청에 대한 응답 역시 대외기관에서 FEP를 거쳐 계정계에 데이터를 적재하는 방식으로 처리하고 있어요.
여러 서비스에 요청을 보냈다면 응답을 확인하는 것도 중요한데요. 요청이 끝나면 채널에서는 계정계로 신용정보조회가 모두 종료되었는지 확인 요청을 보내요. 계정계는 오라클을 조회해서 최종 결과값을 채널로 제공하고요. 많은 금융권에서 일반적으로 사용하고 있는 방법이에요.
프로세스 자체는 잘 돌아가고 있지만 어떤 부분이 아쉬울까요? 몇 가지 아쉬운 점을 소개해드릴게요.
문제 #1: 채널에서 계정계로 불필요한 호출
채널에서 응답 확인을 위해 지속적으로 MCI를 거쳐 계정계를 호출하고 있었어요. 계속 호출할 수 없기 때문에 최대 80번까지만 호출해요. 대부분의 경우 몇 초 내외로 처리되지만, 타임아웃이 발생하면 MCI 호출이 급증하게 되죠.
대외기관의 응답에 따라 불필요한 계정계 호출이 많이 발생하고. 또 이렇게 거래가 많이 쌓이면 어느 거래에서 정확히 오류가 발생하는지 특정하기 어려운 상황이었어요. 항상 오류 확인 및 모니터링을 위해 개발자가 데이터베이스를 직접 조회했습니다.
문제 #2: 심사에 불필요한 데이터를 오라클에 적재
두 번째는 데이터베이스에 불필요한 데이터가 적재되고 있었어요. N개의 서비스 응답 성공 여부가 전부 N개의 테이블에 적재하고 있었어요.
처음 토스뱅크 오픈 시점에는 각 기관별 응답 여부를 하나의 테이블에 하나의 행(Row)으로 관리했습니다. 그러나 여러 개의 전문이 동시에 응답이 도착하면, 비관적 락을 사용하기 때문에 동시성 이슈가 발생하는 경우가 있어서 이런 시스템이 만들어졌어요.
토스뱅크의 해결 방법
그래서 토스뱅크는 이런 문제를 어떻게 해결했을까요? 토스뱅크는 KCB, NICE 등 각 기관에서 보내는 응답을 저장합니다. 각 기관에서 필요한 데이터가 모두 저장됐으면, 최종으로 통합 관리하는 테이블에 모든 데이터를 저장하는 구조를 설계했어요.
비동기 방식의 통신에서 모든 전문이 잘 들어왔는지 확인하는 과정은 중요하지만, 각 전문별 응답 값은 심사에 영향을 미치는 정보가 아니고, 단순히 응답 확인만을 위해 저장되는 데이터였기 때문에 이런 설계가 가능했어요.
해결 방법 #1: Redis 도입
토스뱅크에서는 여러 개의 전문을 한 번에 요청하고 있어요. 요청한 전문에 대한 응답은 모두 비동기로 수신되고요. 그래서 지금 전문 수신 프로세스는 동시에, N개의 전문을 수행할 수 있는 형태에요.
대외기관에서 신용조회한 특정 전문 응답이 들어오면 Redis에 수신이 완료되었다는 정보를 저장해주어요. 메모리에는 고객을 특정할 수 있는 Key 값, 전문이름, 그리고 전문에 대한 응답 정보를 넣어주어요.
응답 정보를 넣어줄 때마다 지금까지 Redis에 저장한 전문 응답 개수와 우리가 요청한 전문 개수를 아래와 같이 비교해서 요청 정보가 모두 수신되었는지 확인을 해요.
private fun isComplete(size: Int) = size == CreditBureauType.getOnlineTelegramSize()
마지막 전문이 응답된 시점에 모든 신용조회가 완료된 것으로 판단하고 심사에 필요한 정보를 테이블에 적재하고 신용정보 조회 단계를 종료합니다.
Redis가 가지는 특징 중 하나인 인메모리 저장 방식은, 하드디스크가 아닌 주기억장치인 RAM에 데이터를 저장하는 방식이에요. 그래서 데이터를 빠르게 읽고 쓸 수 있다는 장점이 있죠. Redis는 이러한 인메모리 장점을 살려 메모리를 임시 저장소로 활용하는 캐싱 전략을 많이 사용됩니다. 이번 토스뱅크 전세대출에서도 각 전문의 응답 데이터는 심사에 불필요한 데이터라고 판단하여 Redis를 도입하기로 했습니다.
해결 방법 #2: 카프카를 이용한 응답 전달
신용정보 조회 단계가 완료되었으니, 완료되었다는 정보를 채널에서 폴링하던 방식은 아래처럼 개선했어요.
기존에는 계정계가 직접 채널에 알려주지 않아 그림과 같이 응답 완료가 될 때까지 채널에서 주기적으로 전자금융서비스(API)를 호출해서 확인했어요.
하지만, 전세대출에서는 응답이 완료되면 Kafka 이벤트를 발행하여 불필요한 호출이 지속적으로 발생하지 않도록 개선했어요. Kafka를 도입한 이유 중 하나는 일반적으로 응답받는데 시간이 꽤 걸리는 경우 비동기 하게 Kakfa 로 응답을 받을 수 있기 때문이에요.
해결방법 #3: 새로운 MSA 구조
지금까지 전세대출에서 신용정보를 조회하는 과정에서 개선한 점에 대해서 디테일하게 설명 드렸어요. 이제 앞서 설명드린 개선점이 반영된 최종 전세대출 MSA 구조와 이전과 달라진 점을 설명해드릴게요.
기존 구조는 채널에서 MCI를 통해 계정계 Monolithic 서버를 호출하고, FEP 솔루션을 활용하여 대외기관에 전문을 주고받는 구조였어요. 새로운 구조는 전세대출 MSA를 통해 채널에서 MSA전세대출 심사 서버를 RestFul API로 호출하고 대외기관에 전문을 fep-gateway로 주고받는 구조로 개선되었습니다.
변화된 부분 중 몇가지를 자세히 살펴보면 다음과 같아요.
- 기존에는 모든 정보를 오라클 RDBMS에서 관리하였으나, 전세대출에서는 원장성 정보가 아닐 때는 Redis를 활용할 수 있도록 개선되었고요,
- 응답값 확인을 위해 채널에서 수많은 조회 요청을 하는 방식이 아니라, 완료 시점에 메시지를 발행하는 이벤트 드리븐 방식으로 바뀌었어요.
개선 효과
구조를 전환하면서 어떤 점이 개선됐는지 알려드릴게요.
MSA는 단일 책임 원칙을 중시해요. 그래서 전세대출 서버는 전세대출만을 담당하고 있어요. 다양한 상품을 함께 관리하던 과거 프로그램에 비해 로직이 간소화됐고, 필요한 내용만 확인할 수 있어 유지 보수에 용이해졌어요. 그리고 기존에는 계정계와 채널 서버가 분리되어 업무가 명확히 나누어져 있었는데요. 계정계 로직이더라도 MSA 환경에서 구현되어 해당 기술 스택을 만족하는 모든 서버 개발자가 기여할 수 있게 되었어요.
또 비용과 시간을 절약할 수 있었는데요. 레디스에 적재하는 응답데이터를 오라클 DB에 적재했다면 전세대출 상품에서만 하루 약 20만건의 데이터를 적재했을 거예요. 전세대출이 출시한지 곧 1년인데, 약 7300만건의 DB리소스를 절약해요. 시간 측면에서는 모놀리식 서버 로직에 비해 회당 0.6~0.7초 감소했어요. 외부정보가 하루에 20건 정도 수행되니 하루에 고객님의 시간도 많이 절약됐습니다.
마지막으로 가장 큰 장점은 장애가 발생했을 때도 영향도가 없다는 점이에요. 기존에는 DevOn 프레임워크에 계정계 서버가 돌아가는데요. 특정 장애가 발생하면 모놀리식 서버 내에 있는 개인여신, 개인사업자 여신은 모두 심사가 불가능한 상태가 됩니다. 하지만, 전세대출은 서버가 분리되어 있어 심사가 가능합니다.