Toss SLASH24

토스 개발자 컨퍼런스 SLASH24 NoLimit

KeyNote

(feat. 토스 CTO 이형석)
  • NoLimit : 풀지 못할 문제는 없다!
  • 토스 앱 누적 가입자수 : 2600만 / MAU : 1900만
  • 토스가 문제 해결을 하기 위해 노력한 개발 문화
    1. 문제의 어려움을 최선의 선택을 할 수 있도록 도와주는 문화
      • 문제점에 대해 누구든지 다양한 의견을 낼 수 있는 문화
      • 문제 해결을 위한 최선의 선택을 함께 할 수 있는 문화
    2. 끊임없이 기술을 학습하는 문화
      • 문제 해결을 위해 다양한 기술을 학습하고 검토하고 적용하는 문화
    3. “최복동”: 최고의 복지는 동료다!
      • 각자가 옆에 있는 동료에게 최고의 복지가 되기 위한 노력하는 문화

리플레이 검증으로 새로운 금융 시스템 안전하게 도입하기 (feat. 토스증권 양승영, 토스뱅크 박종수)

국내원장 프로젝트 MSA 전환 (feat. 토스증권 양승영)

  • 거대한 C언어 기반 모놀리식 코어뱅킹 시스템을 Kotlin 기반 MSA 구조 전환
    • 전환 과정 제약 사항
      • API 스펙을 유지
      • DB 스키마도 유지
      • 주요 비즈니스 로직 또한 유지
    • 전환 과정 문제점
      • 기존 시스템의 변경: 기존 코어뱅킹 시스템에 변경 사항 반영 필요
      • 테스트 코드 작성 부담: 거대한 코어뱅킹 시스템의 모든 기능에 대한 테스트 코드 작성 부담
      • 한번의 통합 테스트를 위해 필요한 많은 선행 작업들
  • 아키텍처 전환을 위해 수정 > 배포 > 테스트 > 검증 사이클 무한 반복..
  • 테스트 > 검증 구간을 자동화 계획!!

Read Verifier

  • 조회 Read API 검증 자동화 모듈
  • API 호출을 비동기로 리플레이하면서 서비스 전환 검증
  • 레거시 API차세대 API 를 비동기적으로 각각 호출하여 각 응답 결과값 비교
  • Read API 검증 결과는 주기적으로 리포팅하여 어드민 기능 지원을 통해 검증 결과 확인

Write Verifier

  • 쓰기 Write API 검증 자동화 모듈
    • Read 보다 더 많은 고민
  • Write 요청에 대해 레거시 API 처리되기 전, Gateway 에서 차세대 APIIntercept 하여 1차 처리
    • 차세대 API 처리 결과를 Redis 저장
    • 차세대 API 에서 수행한 CUD 쿼리는 조회 쿼리로 변경하여 저장
    • P6Spy : 애플리케이션에서 실행되는 쿼리 수집 도구
    • ANTLR : 수집된 CUD 쿼리를 분석해 조회 쿼리 변환 도구
  • 이후 다시 레거시 API 로 처리하고, Verifier 모듈로 검증 요청
    • 레거시 API 의 결과와 차세대 API 의 결과를 비교
  • 실시간 리포팅으로 개발자가 눈으로 확인하는 것보다 더 빠르고 정확하게 검증

성과

  • 레거시 시스템에서 발생하는 데이터를 기반으로 안정성 보장하며 전환 집중
  • 총 182개의 API 를 효과적으로 검증
  • 테스트 시간 효과적으로 절약

긴 생애 주기의 프로젝트 관리 (feat. 토스뱅크 박종수)

대출 상품 같은 생명 주기가 긴 서비스를 개발하고 관리한다면?

  • 대출 상품을 가입하는 경우, 짧게는 1년 길게는 10년 이상 데이터 관리 필요
  • 10년 동안 변경될 기준금리에 맞게 실제 금리 반영 필요

미래에 실행될 로직을 ‘지금’ 테스트해볼 수 있는 방법은?

  • 독립된 테스트 환경에서 시간을 바꿔가며 테스트 시뮬레이션 실행
  • 실시간 거래, 배치 거래 데이터를 표준화
  • k8s 활용한 독립적인 시뮬레이션 환경 구축
  • 1일 1회 DB 복제 & 시뮬레이션 DB 자동 생성
  • Redis 활용하여 시뮬레이션 테스트기준시간 관리
  • 시뮬레이션 거래 과정을 DB 값을 조회하여 검증

CPU Observability 높이는 Hyperthread 톺아보기 (feat. 토스 최준우)

CPU 사용률 50% 이상시, Hyperthread 사용 자제 필요하다는 이슈 발생 !!

Hyperthread

  • 인텔(Intel)에서 개발한 기술로, 하나의 물리적 CPU 코어가 동시에 두 개의 스레드를 처리
  • 하나의 물리적 코어를 두 개의 논리적 코어로 분리하여 작업
  • 두 개의 논리적 코어는 물리적 코어의 자원 공유
  • 하나의 스레드가 대기 상태일 떄 다른 스레드가 실행되어 CPU 자원 활용 극대화 가능
  • 하지만, 무분별한 Hyperthread 사용은 다른 코어 CPU 악영향 발생

Hyperthread Observability

  • Elasticsearch 기반의 성능 측정 계획
  • Linux-KI : CPU 의 double busy 라는 Hyperthread 매트릭 정보 수집
  • perf : 리눅스 CPU Instruction 성능 측정 도구

Next 코어뱅킹, MSA 와 MySQL 로 여는 평생 무료 환전 시대 (feat. 토스뱅크 장세경, 김준우)

토스뱅크 코어뱅킹 MSA 전환 배경

  • 기존 토스뱅크의 코어뱅킹 모놀리식 시스템의 단점을 해결하기 위해 MSA 전환 계획
    • 코어뱅킹 + 오라클DB <> 채널계 + MySQL 구조
  • 코어뱅킹 시스템의 오라클 의존성을 줄이기 위해 MySQL DB 전환 계획
    • 오라클 장점 : 신뢰성과 안정성, 대용량 데이터 볼륨 처리 확장성, 뛰어난 성능, 오랜 운영 노하우
    • 오라클 단점 : SFOP 문제, 비용 문제, 제한적인 Scale-out 문제
  • 오라클DB 보안책
    • Redis 분산락, SAGA 패턴Application Layer 에서 트랜잭션 관리 보장
    • MySQL Replication 전략 등 높은 수준의 데이터 처리 확장성, 빠른 Scale-out 전략 보장
    • MySQL MVCC 기술 사용으로 효율적 데이터 동시성 제어 보장
    • MySQL 또한 오라클 못지않은 오랜 운영 노하우 보유

코어뱅킹 신규 서비스 MSA 개발

  • 새로운 신규 서비스는 MSA 와 MySQL 기반으로 개발 진행 👉 점진적인 MSA 전환
  • 트랜잭션이 중요한 내부 서비스는 동기식 트랜잭션 처리, 외부 트랜잭션 처리는 비동기 트랜잭션 처리
  • API 동시성 제어를 위해서는 분산락을 사용하고, DB 데이터 동시성 처리를 위해선 비관적 락 사용
  • 여러가지 거래 가능 검증을 위해 코루틴을 활용한 비동기적 처리 방식으로 지연 감소
  • 24/365 서비스 지원을 위해 전일자 스냅샷을 통해서 거래 대사 처리
    • 전일자 데이터 스냅샷 저장 > 거래 내역 기준 역산하여 잔액 원장 등 데이터 처리
    • 하둡을 사용하여 전일자 데이터 저장&조회를 통한 대사 처리

신규 서비스 테스트 자동화

  • 비중 : 개발 20% / 테스트 80% 👉 개발 80% / 테스트 20%
  • 테스트 자동화를 위한 과정
    • Local: 단위테스트 코드 작성 👉 프로그램 정합성 검증
    • Dev: E2E 서버 테스트 👉 업무 정합성 검증
      • E2E 서버 > 타켓 서버 API 테스트 자동화 도구 개발을 통해 실시간 E2E 테스트 검증
    • Live: 이상거래탐지 서비스 개발 👉 데이터 완결성 검증
      • 하둡 저장 데이터 기준 이상거래탐지 배치 프로그램 개발을 통해 실시간 데이터 검증

외화 예금 MSA 신규 개발 성과


SSE 이벤트 푸쉬로 불필요한 Polling 제거하기 (feat. 토스증권 전연빈)

Push 서버 개발 배경

  • 실시간 데이터 정보 조회 제공을 위해 다양한 도메인 정보를 3초마다 Polling 시스템으로 요청 & 수집
    • 이슈 발생 : 급증한 트래픽으로 Polling 시스템의 DB 부하 발생
  • 실시간 Event 트랜잭션 완료 시 각 도메인 정보를 조회하고, 클라이언트에게 전달할 수 있는 Push Server 개발 필요

Push 서버 구성

WebSocket vs SSE

구분 SSE WebSocket
Protocal HTTP WebSocket
Direction 서버사이드 단방향 양방향
Auto Reconnect Yes No
Cookie Yes No
Response Type Text text or byte
Usage 불필요한 Polling 제거
개인화 데이터를 이용한 이벤트 푸쉬 가능
양방향 통신 필요 시 사용
송/수신량 데이터량 높은 서비스에 유리

SSE ServerSendEvents

  • HTTP 의 Content-Type : text/event-stream 을 통해 데이터 파이프라인을 구축하여 서버에서 클라이언트로 데이터를 보낼 수 있는 구조
  • SSE 서버는 메시지 브로커로부터 데이터를 수신하여 클라이언트로 데이터 전달
  • Broadcasting, Unicasting 방식 모두 지원 가능

SSE Sever 구성

SSE 사용 사례

  • Broadcasting 방식 활용
    • 이벤트성 단일 채팅방 서비스 구축
  • Unicasting 방식 활용
    • 개인화된 데이터 정보 조회 서비스 구축
      • 개인 보유자산 실시간 정보 PUSH 처리
    • FCM 안드로이드 PUSH 알림 대체
      • 비회원에게는 FCM 으로 푸쉬 알림 / 회원에게는 SSE 서버로 푸쉬 알림
      • Redis Pub/Sub 를 이용하여 회원 여부 판단하는 세션 기능 개발

Message Broker 선택 전략

  • Kafka
  • Redis Pub/Sub
  • NATS : Go-Lang 기반 Pub/Sub 메시징 분산 처리 지원 오픈 소스 메시징 시스템

성능 테스트 비교

최종 시스템 구성


클릭 한 번으로 테스트 45만 개 완료! 테스트 자동화 플랫폼 구축기 (feat. 토스페이먼츠 박정웅)

기존 테스트 자동화 문제점

  • 표준화 되지 않는 다양한 컨텐츠의 테스트 자동화 도구 👉 통합된 테스트 자동화 플랫폼 제공
  • 표준화 되지 않는 자동화 코드의 공유 👉 통합 테스트 자동화 플랫폼 활용한 공유
  • 테스트 결과 가공의 어려움 👉 테스트 결과의 이력 관리 및 커스텀 리포트 자동 생성

Playwright 활용한 테스트 자동화 플랫폼

Playwright

  • Microsoft 에서 개발한 E2E 자동화 테스트 도구
  • VSCode 개발자 도구 연동하여 개발 가능
  • 테스트 파일 실행 제어
  • 테스트 파일 실행 리포트 자동 생성

Playwright 실행 과정

Test Automation Platform 구성

Test Automation Platform 구성 요소

Test Automation Platform 문제

  • 테스트 종류마다 다른 리소스 크기로 컴퓨팅 리소스 문제 발생
    • 👉 테스트 러너의 동시 실행 가능한 Playwright 실행 수 제어
    • 👉 메시지 큐를 사용하여 편린한 테스트 러너 인스턴스 Scale-out 구조 설계
    • 👉 테스트 결과를 청크 단위 처리

Test Automation Platform 테스트 결과 조회

Test Automation Platform 테스트 결과


웹뷰로 시작되는 Nest.js 프레임워크로 똑똑하게 서류 스크래핑하기 (feat. 토스뱅크 박진수)

  • 서비스 웹뷰 <> 스크래핑 웹뷰 분리하여 스크래핑 웹뷰는 보이지 않도록 한 상태에서 스크래핑 처리 진행
  • 웹뷰에 서버를 기동하는 방법으로 문제 해결
  • Nest.js 를 통해서 웹뷰에 서버를 올리고, API 통신 처리
  • FE 에서는 Nest.js 서버로 요청을 하고, 복잡한 비즈니스 로직은 Nest 서버에서 처리
  • Nest.js 인메모리 활용한 동시성 데코레이터로 동시성 제어 처리
  • 모니터링을 위한 APM Sentry 도입
  • 웹뷰에서 Nest.js 서버를 기동을 위해 PolyPill 를 활용

미처 알지 못했던 Kernerl 까지 Observability 향상시키기 (feat. 토스 이항령, 이재성)

ebpf 를 활용한 CPU 사용률 분석

  • 커널에서 블랙박스 형태로 모니터링의 어려움이 있었는데, ebpf 를 통해 커널까지 모니터링
  • numa 아키텍처 : CPU 와 메모리 간의 간격을 줄이기 위한 아키텍처
    • CPU 와 메모리의 간격을 줄이기 위해 remote access 를 사용

Redis latency 이상현상 파악

  • 20~50 ms 지연이 발생하여 문제 파악 시작
  • TCP 덤프를 통해서 네트워크 영역부터 분석
  • 네트워크 장비와 애플리케이션 사이의 지연 발생 확인
  • perf trace 를 사용해서 매트릭 정보 수집하였지만 로그 수집이기 때문에 정확한 정보 수집 불가 > ebpf 로 분석 시작
    • pixie : ebpf 모니터링 도구
  • 알고 있는 지식 기준으로 해볼 수 있는 모든 방식을 시도해보고, 안되면 기초 지식부터 하나씩 올라가본다!
  • Observability 를 적극 활용하여 근본적인 원인을 찾을 수 있다!

보상 트랜잭션으로 분산 환경에서도 안전하게 환전하기 (feat. 토스뱅크 이신동)

분산환경이 만들어진 이유

  • 모놀리식 시스템 레거시 시스템 개선 필요
  • 기존 코어뱅킹 시스템을 MSA 구조로 분리 욕심
    • 하지만, 거대한 코어뱅킹을 분리는 무리
    • 그래서, 신규 서비스는 바로 MSA 구조로 설계
  • 환전은 레거시 원화 시스템 & 신규 외화 시스템 2가지 모두 활용하는 신규 MSA 서비스
  • 분리된 시스템 간 트랜잭션 처리를 위한 분산 트랜잭션 구현 필요

분산 트랜잭션 처리: 2PC vs SAGA 패턴

2PC Two-Phase Commit

2PC

  • Coordinator 코디네이터에서 트랜잭션을 관리하고, Prepare Phase & Commit Phase 2단계로 구성
  • 각 시스템에서 트랜잭션 처리 요청하여 성공인 경우, 커밋 처리 / 실패인 경우, 롤백 처리

SAGA 패턴

SAGA 패턴

  • 2PC 보다 높은 가용성/확장성 제공
  • 2PC 보다 롤백 트랜잭션을 직접 관리해야한다는 단점
SAGA 패턴의 환전 서비스 구현
  • 환전 서비스가 SAGA 패턴의 오케스트레이터가 되어서 원화/외화 트랜잭션을 관리
  • 다음 트랜잭션 실패하는 경우, 실패 보상 트랜잭션을 이전 서비스로 요청 처리
  • 트랜잭션 처리 순서도 중요 (원화 출금 > 외화 입금 순서 필수!)
네트워크 통신 방식: HTTP vs Messaging
  • HTTP : 동기 vs 메시징 : 비동기
  • SAGA 패턴의 구현은 무조건 메시징이 아니라 정확한 동기 처리를 위해선 HTTP 방식으로 선택 가능
  • 하지만, 보상 트랜잭션은 비동기 처리를 해도 되기 때문에 비동기 방식으로 선택 가능
에러 핸들링
  • 타임아웃과 같은 요청 실패에 대해서는 결과 확인 요청을 통해 성공 처리
    • 타임아웃이 발생하였을 경우, 요청 서버로 결과 확인 요청
    • 요청 서버 결과 확인 요청에 대한 결과 따른 예외 처리 진행
  • 결과 확인 요청마저 실패한다면, 지연 메시징 처리를 활용하여 요청 서버로의 요청을 Backoff 재시도 처리
  • 환전 서버가 장애 발생하였을 떄는, 오케스트레이션의 트랜잭션 이력 기준 Batch 재처리
  • 보상 트랜잭션 비동기 처리 중 실패하는 경우 Dead Letter 처리를 통해서 해결

Eventually Consistency: Consumer Dead Letter(CDL)

  • 메시지를 수신하는 도중 에러가 발생하는 경우, Consumer Dead Letter 메시지를 발행하여 재시도 처리
  • Dead Letter 서버 별도 구성하여 DL 메시지를 다시 발행 처리

Transaction Messaging: Produssor Dead Letter(PDL)

  • 메시지를 발행하는 도중 에러가 발생한다면, Produssor Dead Letter 메시지를 발행하여 재시로 처리
  • Dead Letter 서버에서 DL 메시지를 다시 발행 처리

Monitoring

  • 각 원화/외화 서비스의 DB 를 ETL 로 별도 DB로 데이터를 저장
  • 배치를 통해 별도 DB 의 이상 트랜잭션을 감지하고 알림

결론

결론


토스뱅크가 차세대를 하지 않는 이유: 지속 가능한 마이그레이션 전략 (feat. 토스뱅크 차영록, 김인회)

  • 금융권 차세대 프로젝트는 대규모 프로젝트를 기술 부채를 해결하기 위한 프로젝트
  • 보통은 워터폴 방법론으로 차세대 프로젝트를 진행하기 때문에 큰 리스크를 가지게 된다.

Strangler Fig Pattern

  • 기존 시스템을 점진적으로 새로운 시스템으로 대체하는 전략
  • 모놀리식 시스템의 기능을 하나씩 마이크로 서비스로 전환
  • 낮은 응집도와 높은 결합도의 모놀리식 서비스를 UseCase 단위로 독립적으로 분리
  • 좋은 소프트웨어는 코드보다 철저한 설계로부터 나온다!!
  • 효과적인 도메인 문서화로 지속적인 관리 효과를 발현
    • 글보다는 시각적인 문서화가 더욱 더 이해하기 쉽다!!
  • 다양한 시각과 의견으로 최선의 선택을 하고, 최적의 비즈니스 로직 유지 가능하다!!
  • 부수효과를 막기 위해 기존 기능과 동일한 출력을 만들어내야 한다.
  • 분할정복 리팩토링을 통해서 기능 뎁스/리프 별로 리팩토링하고, 흡수하고, 반복한다
  • 리팩토링 코드를 검증하기 위해서 레커시/리팩토링 코드를 동시 병렬 실행하여 비교군을 만든다
  • 검증 실패하는 경우, 다시 분석 > 설계 > 구현 단계를 반복한다
  • 콘웨이 법칙
    • 시스템은 조직을 닮는다. - 콘웨이

대규모 사용자 기반의 마이데이터 서비스 안정적으로 운영하기 (feat. 토스 신윤재)

마이데이터

마이데이터 구조

  • 마이데이터 : 여러 금융기관에서 개인의 신용 정보 조회/제공 서비스

마이데이터 서비스 장애 대응

마이데이터 서비스 장애 대응

  • 제공 기관의 요청을 조절하여 제공 기관의 부하 제어 필요
  • Resilience4j 서킷-브레이커 적용하여 제공 기관으로 가는 트래픽 제어
    • 하지만 멀티 인스턴스 구성 환경에서는, 각 인스턴스의 서킷-브레이커 상태를 알 수 없기 때문에 장애 발생 가능

트래픽 제어 Coordinator 서버

트래픽 제어 Coordinator 서버

  • 별도의 트래픽 제어 코디네이터 서버를 구성
    • 장애포인트를 일원화, 유연하고 확장 가능한 별도 코디네이터 시스템을 구현
  • 코디네이터에서 외부 업체별 서킷-브레이커 상태를 저장하고, 각 서비스 인스턴스는 코디네이터로 서킷-브레이커 상태를 조회
    • 각 서비스 인스턴스는 로컬 캐시로 서킷-브레이커 상태를 저장하여, 제공 기관에 요청을 제어

토스 시스템 부하 개선

토스 시스템 부하 개선

  • 제공 기관의 응답이 느려 바로 성공 응답이 아니더라도, 유저 이탈 이후 다시 진입하더라도 결과를 다시 확인할 수 있도록 비동기 처리
    • 하지만, 인프라 리소스에 대한 부하 발생
    • 이를 해결하기 위해 Websocket & Polling 활용
  • APP 에서 Websocket 를 통해 마이데이터 서비스와 연결하고, API 요청에 대한 응답은 바로 처리한다
  • 그러면, 공용 네트워크 리소스에 대한 부하 해결

유동적인 대용량 데이터 처리 개선

유동적인 대용량 데이터 처리 개선

  • 유저의 패턴을 분석해서 유저 인입이 적은 날에는 배치 처리량을 늘려 서버 부하를 일자별로 분산한다
  • 코루틴 채널을 통해서 배치 프로그램을 성능 개선

결론

결론

  • 엔지니어는 공학으로 문제를 해결하는 역할을 수행한다