본문 바로가기
Etc

[SLASH24] 토스 컨퍼런스 SLASH24 후기

by 곰민 2024. 9. 19.

이번에 열린 토스 SLASH24 컨퍼런스에 당첨이 되어서 다녀오게 되었다.

같은 금융 도메인에서 종사하고 있기에 SLASH24를 통해서 많은 인사이트를 얻을 것을 기대하고 참석하였다.

다양한 세션에서 많은 좋은 경험을 하게 되었다.

SLASH24에서 경험한 세션 내용에 간략한 요악과 이번 컨퍼런스에 대해 느낀 점에 대해서 적어보았다.

 

 

 

웰컴 기프트 백


 

기프트 백은 무엇을 줬을까?

이것부터 확인하고 들어가자.

 

 

 

 

입구에서 출입증을 만든 뒤에.

좀 더 들어가서 기프트백을 주는 곳에 출입 목걸이를 보여주면 기프트백을 준다.

 

 

세일즈 포스 양말과 노션 아이템을 설문조사로 받은 것을 감안한다면, 생각보다 간단한 구성이다.

우루샷 박스, 토스 간단한 스티커, nolimit 키링? 같은 것을 준다.(물도 한 병 주는데 다 마셔서 차마 담지 못했다.🤣)

개인적으로 제일 마음에 들었던 것은 세일즈 포스 부스에서 고른 양말이다. (귀엽다)

 

들었던 세션


 

들었던 세션들을 표기해 보았다.

 

 

 

왼쪽 가운데 오른쪽 순으로 102, 103, 104 호에서 진행했던 것으로 기억한다.

가운데 세션을 대부분 들어서 크게 이동할 일 없이 잘 들었던 것 같다 😀

 

세션 내용 정리


 

그럼 들었던 세션 내용을 간단하게 정리해 보자.


Replay 검증으로 새로운 금융시스템 안전하게 도입하기


 

 

기존 모놀리식 구조의 c 기반의 레거시 원장 시스템을

kotlin 기반의 msa 원장 시스템으로 전환하는 과정에서 몇 가지 제약사항을 기반으로 전환하는데.

 

제약사항은 다음과 같다.


1. api 스펙 유지
2. db 스키마 유지
3. 주요 비즈니스 로직 유지

위 3가지 재약사항을 기반으로 전환하면,

기존 원장시스템 사용하던 것이 새로운 시스템에서 잘 활용이 가능하고 리팩도 가능하기 수월 해지는 것.

하지만 몇 가지 어려움이 존재하는데.

기존 시스템의 변경에 따른 테스트코드가 없이 작성하기에 부족한 리소스와
통합 테스트를 위해서는 선행작업들이 필요하다.
수정 --> 배포 --> 테스트 --> 검증 및 확인 --> 수정 이 사이클이 무한루프처럼 굴러가는데 
그중 테스트 --> 검증 및 확인 이 작업을 자동화를 해보자라고 결정한 것.

 

아이디어

 

Read Verifier

Read APi 검증 자동화
API 호출을 비동기로 리플레이하자.
차세대 원장을 호출하게 하고 각각의 응답을 비교하는 방식.

gateway --> kafka 메시지로 발행
verifier가 api 응답 결과를 비교한다.
카프카를 활용해서 운영환경에서 안전하고 정확한 검증을 통한 어드민 기능이 지원된다.
검증 결과를 주기적으로 리포팅하도록 전환
차세대 원장을 운영환경에 적용할 때 심리적으로 안정감을 줬다.

 

 

write verifier 

gateway 서버에 들어오는 요청을 집중해서 보고 기존원장 시스템에 보내기 전에 intercep 한 다음

새로 변경한 차세대 원장으로 보내고 차세대 원장에서 요청처리하고 트랜잭션 마치기 전에 cud 쿼리를 redis에 넘겨서 조회쿼리 + 쿼리 결과로 변경해서 저장.
트랜잭션 롤백
처리 결과 + 조회쿼리를 레디스에서 가져와서 verifier에 넘기고 실제 db에서 처리된 데이터를 찾아 결과 비교.

c 기반 기존 구조랑, msa 코틀린 구조에 각각 db를 사용하고 데이터를 각각 넣고 데이터 검증을 하기에는 테이블이 많아서 쉽지 않았고,
db를 하나만 사용하고 트랜잭션을 롤백하는 방식이 좀 더 나아 보였다.

요청을 미리 처리해 보고 롤백하는 방식
동기식으로 동작하기 때문에 성능에 영향을 주어 개발 환경에서만 사용
검증을 위한 기능 라이브러리로 제공


결과 실시간 리포팅하도록 작업.

 

생애 주기가 긴 대출 상품은 시간변경을 하여 테스트를 어떻게 할까?


 

1. 장기 대출 상품 테스트의 어려움

 

토스 뱅크 상품 대출 기간 1~10년
10년이라는 기간 동안 발생할 이벤트에 대해서 약정서를 통해서 고객과 약정한다.

기준금리 변경 시 기준금리는 변경되고 가산금리는 유지되어야 하는데,
10년 뒤에도 잘 돌지를 어떻게 볼까?

실행, 해지와 같은 데이터는 종단 테스트가 가능했으나
기준금리 변경과 같은 몇 달이 걸리는 것은 종단 테스트가 힘들었다.

데이터를 조절해서 대출일자를 바꾼 다음에 테스트를 해보면 괜찮을까?
가능하기는 하나.
데이터를 어떻게 변경해야 할지, 데이터를 잘 조절해야 한다.
근데 문제는 데이터를 조절한 게 문제가 되는지, 로직이 문제가 있는지 알기가 쉽지 않다.


2. 독립적 테스트 환경 구축

 

단일 서비스, 단일 데이터 베이스
대출 시스템이 하나의 디비만 보기 때문에 디비만 독립적으로 설정하면 다른 시스템에 영향을 덜 받고 잘 테스트하기 쉽다.
독립된 테스트 환경에서 시간을 바꿔가며 거래 실행 및 검증을 하는 방식.

 

이 문제를 해결하기 위해 k8s를 활용한 독립적인 시뮬레이션 환경을 구축하는데

이 환경의 핵심은 다음과 같다.

- 독립된 데이터베이스 사용
- 사이드카 방식으로 각 파드(Pod) 별 시뮬레이션 구동

 

독립된 디비를 구축하는 방법
매일 한 번씩 운영 디비와 테스트 디비에서 매일 스키마를 가져오도록 설정되어 있음.
시뮬레이션 디비가 별도로 존재.

매일 운영 DB에서 프로시저를 통해 사용자를 생성하고 스키마를 동기화하여 최신 상태 유지


3. 시뮬레이션 프로세스

테스트 과정은 다음과 같이 진행한다.


- 새로운 DB 사용자 생성 및 DB 할당 (3분 이내)
- 레디스를 활용한 시간 설정
- 시간 변경 → 실시간 거래 → 배치 작업 → 검증의 반복

CPU Observability 높이는 Hyperthread 톺아보기


 

 

하이퍼 스레드에 대한 간단한 개념을 한번 짚고 간다.

cpu 구조에 대해서 간략하게 설명을 해주시는데 아래와 같다.

하나의 명령을 수행할 때
여러 개의 명령어를 동시에 실행한다는 것이 포인트.

1. 파이프 라이닝
2. out of order dispatch 빈 공간을 줄이는 방식
3. super scalar 구조 - 실행장치에 동시에 디스패치함.


stall, bubble과 같이 비는 스테이지를 줄이고자 나오는 게 하이퍼스레드.

그러나 코어를 쪼개서 사용하면 기똥차지 않나요?라고 생각했으나.. 

그때그때 다르다.

noisy neighbor 문제
ml 플랫폼과 같이 cpu bounded가 많다면 하이퍼스레드 비활성화를 권장하기도 하기도 한다.
파이프라인이 빌 때 스테이지를 이용해 이점을 얻는 건데 스톨 걸릴 확률이 높다.

장단점을 고려하자
하이퍼 스레드가 사실 필요한가? 


Elasticsearch 활용

측정해 보자.

cpu 사용률은 정확한 정보를 제공하지 않는다
cpu 측정 중에서 busy 즉 사용 중이다라고만 나오기 때문에 알 수 없다
인스트럭션 처리량을 측정해야 한다.

linux -ki
perf

두 가지 툴을 활용하여 모니터링 및 비교작업.

두 개의 cpu가 같은 작업을 할 때 경합이 발생하고 더 오래 걸리는 게 문제.
cpu 병목현상 파악 가능한 지표가 있을까?
cpu performance counter라는 지표가 있다

intell cpu는 특정 병목현상이 있으면 performance cunter에 기록하고 이걸 가져올 수 있다.
인텔에서 perf에 여기에 넣어두었다.
하이퍼스레드로 인해 백엔드 병목현상이 가려질 수 있다.


intel의 탑다운 모니터링 중 백엔드 섹션에서 코어바운디드 항목을 참고하면 도움이 된다.
프로메테우스, ebpf를 활용해서 성능측정과 탑다운 모니터링을 할 예정
사용 중이 워크로드의 특성을 잘 파악하고 하이퍼스레드를 어떻게 사용할지 잘 파악해 볼 예정이다.

Next 코어뱅킹, MSA와 MySQL로 여는 평생 무료 환전 시대


 

해당 세션은 시작 사진을 못 찍어서.. 인상 깊었던 빠른 환전 속도 성과 자료로 대체한다. 😅

 

문제상황

모놀리식의 코어뱅킹 시스템을 msa 기반의 도메인 서버로 개선 중.

msa로 서버가 분리되어도 db는 oracle을 여전히 의존 중.

환전서버에 한해서 mysql로 디비분리를 해보자.

 

트랜잭션이 하나의 동기면 너무 느리고 tps 받기도 힘듦 그래서 카프카로 분리하였다.

 

잔액변동을 막는 동시성 제어가 필요하고

레디스 분산락 활용으로 api 락

계좌 디비는 디비락

 

계좌 상태 거래제한 가능고객 등등 다 거래가능 검증  

여기서 레이턴시를 줄이기 위해서 코루틴활용

관련 거래 등록 및 잔액 수정

 

무중단 환전 서비스는 어떻게 구현했는가?

 

은행이 자정 근방에 거래가 안됨

회계시스템과 연관이 있음

 

잔액 대사

00시 00분으로 고객계좌 잔액과 은행잔액이 같아야 한다

거래를 막아서 잔액산출

 

토스는

원화예금에서

거래허용 후 데이터 보정처리함

1. 00분에 전일자 스냅샷 테이블을 만든다

2. 00분 이후에 거래내역을 확인한다

3. 거래내역을 바탕으로 잔액을 역산하여 전일자 스냅샷 테이블을 보정한다

 

일자별 계좌별 pk로 잔액만 기록

 

테스트 자동화

단위테스트

E2E 서버 고객의 시나리오를 코드화해서 넣어둠

Live : 이상거래탐지서비스 운영환경에서 발생하면 안 되는 데이터가 발생했는지 확인

이상거래탐지 배치.

 

SSE 이벤트 푸시로 불필요한 Polling 제거하기


 

그렇다 정신이 없어서 못 찍었다. 🤣

 

내용으로 들어가자.

 

보유 주식 등의 금액이

폴링으로 데이터 실시간으로 가져오고 있다.

 

Gateway에 aggregation api에 3초 별 polling

Redis oracle mysql cpu사용량이 높아지고 있는 상황이었다.

 

실시간으로 가져가도 변동이 크지 않기에

특정이벤트에만 기민하게 반응하도록 변경해 보았다.

 

push 서버를 Sse vs websocket 둘 중 어떤 것을 활용해 볼까?

 

Websocket 

  1. 양방향통신
  2. 송수신량 데이터 많을 때

Sse

  1. 불필요한 polling 제거
  2. 개인화된 이벤트 푸시

sse에서는 

Content type

Text/event-stream

 

클라 <-- sse <-- 브로커 서버

 

브로드캐스팅

웹플럭스

브로드캐스팅의 경우 브로커에게 메시지 받고 컨버팅작업

커넥트 메서드 호출만 함

 

그렇다면 유저별 개인화된 데이터 푸시는?

유니캐스팅

Sse 서버는 유저별 채널을 만듦

클라이언트와 커넥션하고 데이터 받음

 

주문체결이벤트가 발생되면 db update

Sse 서버이벤트 두고 그때만 호출

 

Fcm push server --> redis

Sse 서버는 유저 관련 정보를 redis에서 가져오고

세션테이블을 별도로 사용히지 않음

 

Sse 서버 사용 시 적어도 한번 전송하는 카프카와 덜 어울릴 것 같아 Redis pub sub이 생각났다.

카프카처럼 모든 데이터를 받지 않아도 된다.

 

Broker throughtfull 더 나은 게 없나?

우리는 Nats를 활용한다.

 

웹플럭스로 하트비트구현 한 부분이 2*n 초로 끊어짐

 

K8s 클러스터 http l7 tcp proxy 덤프를 떠보았다.

이미 끊어진 connection에 ack를 날리니 Rst 발생했다.

 

장비문제였다.

 

클릭 한 번으로 테스트 45만 개 완료 테스트 자동화 플랫폼 구축기


 

문제점!


1. 표준화되지 않은 테스트 
2. 표준화되지 않은 테스트 코드
3. 테스트 경로 가공의 어러움 - 증적

45만 개 되는 테스트 케이스 자동화 관리 가능하게 했다!

사용한 기반 기술로는 nodejs, playwright

playwright를 사용한 이유? 

1. 테스트 코드 필요한 대부분 함수 제공
2. vscode 연동
3. 리포트생성 도구 제공

명령어 실행 시 main, worker 프로세서 생성
테스트 실행, 결과 처리 통합 제공.

간단하게 보는 platform 구성 요소는
admin server와 test server가 존재
test runner는 palywirght 프로세스 실행, 테스트 코드 제어하게 된다.


전체 프로세스 관점에서 테스트 코드 흐름

1. 어드민 서버에 티스트 실행 요청, 조회
2. SQS : 테스트 실행 요청량 제어
3. 테스트 러너 : test code 실행
4. s3 : 테스트 코드 저장소

 

테스트 종류마다
필요한 리소스 크기가 동적인데 어떻게 해결할까?

해결법
1. 러너 인스턴스 동시 실행가능한 최대 playwright 실행 수 제어.
2. 어드민서버와 테스트 러너 사이에 메시지 큐를 둬서 테스트 요청정보를 줌. run id, s3 path

queue에 쌓이는 수에 대비해서 runner를 조절하는 방식.

테스트 실행에 대한 결과 리포팅은?


report 활용 시 대량 처리 시 oom이 발생하는 문제가 있었다.

각각의 결과를 memeory에 올려두지 않고 chunck단위로 처리하는 방식으로 해결
playwright는 report interfaace에 필요한 event handler를 활용
리포트에 대한 chunk size 설정.

테스트 자동화 코드 작성도 코딩이다.

 

1. 코드 품질관리
2. 자동 빌드
3. 코드 통합
4. 코드 리뷰

 

위 프로세스를 통한 배포서버 운용.


문제점이 존재하는데.


실행할 테스트 파일 찾는 게 일이다!

s3에서 테스트 파일을 다운해야 하는데 테스트 파일명은 테스트를 명확하게 표현할 수 없기 때문에 매핑 해결방안이 필요했다!

테스트 케이스 테이블에
테스트 케이스 id , 테스트 명으로 매핑을 해보자


테스트 케이스 검색 and 실행 가능.
테스트 실행을 위해서 테스트 파일명을 전혀 몰라도 되고
테스트 명만 알면 됐다.

의존성은 어떻게 관리해야 할까?


하나의 테스트파일을 여러 개의 js파일로 만드는 방법으로 해결해 보자!

테스트 코드 작성 시 git에 머지함.
배포서버는 sync를 통해서 업데이트함
어드민 서버는 s3에 업로드하게 됨.
테스트 케이스 아이디, 매핑과정을 함.
그리고 배포.

jacoco 연동을 통한 코드 커버리지 체크까지 가능하다.

대외계 구조 개선과 모니터링 강화로 시스템 연속성 확보하기


 

이번 세션은 102호에서 진행되어서 이동하느라 세션 앞부분을 자세하게 듣지 못하였다 🫨

사실 데이터 센터 모니터링 관련 내용에 대해서 지식이 부족하여 잘 알아듣지 못한 부분도 존재하였다...

 

그래도 나름 이해한 부분을 정리해 보자면.

 

네트워크 연결에서 단일 장애점(Single Point of Failure)은 큰 위험을 초래할 수 있다.

단일 인터넷 서비스 제공자(ISP) 또는 중복되지 않은 네트워크 경로에 의존하면 그 경로가 실패할 경우 전체 서비스 중단으로 이어질 수 있다.

위 문제를 해결하기 위해 이중화 작업이 필요하였고 이중화 작업을 진행하였다.

 

모니터링의 경우

RTT(Round Trip Time) 모니터링은 신호가 소스에서 목적지까지 왕복하는 데 걸리는 시간을 측정하는 중요한 네트워크 성능 지표를 측정한다.


RTT 모니터링 구조
CURL&MTR --> zabbix -->  grafana

curl 은 옵션 사용 시 json 포맷을 제공한다.


데이터 대시보드 구성은
데이터센터 회선별 rtt 모니터링

상세 대시보드에서는
한 개의 도메인에 네 가지 rtt 값을 확인 가능하다.

인터넷구간에 문제가 생겼을 때 환경별 rtt 체크 가능하게 해 두었다.

 

핵심은

이중화 구성을 통해서 다양한 메트릭 확보, 네트워크 우회경로 확보 했다는 사실이다.

 

대외계 성장기


여기도 사진을 못 찍었다 하핳

한 가지 생각나는 점은
발표하셨던 분이 아재개그를 두 번을 치시는데.....
대외계 -> 대에계들 모르시죠?
Nat, proxy, gslb (npg) 나쁘지 않죠?
맨 앞에서 세션을 들었는데 왠지 양옆에 앉으신 분들이
팀원분들 이신 것 같은데 위 내용을 들으시곤 격한 반응을 보이셨던 게 기억에 난다..ㅎ

 

대외계에 대해서 간략하게 설명을 해주신다.

보통 금융서비스를 제공하는 데 있어서 대외 기관과 통신을 해야 하는 케이스들을 말한다.

 

필수사항
vpn(데이터 암호화) -- 로드밸런서 -- gslb

선택 사항
두 개의 데이터 센터를 사용.

tls 활용 암호화, ipsec을 활용하여 vpn을 통해 보안 강화
로드밸런서를 통해 트래픽을 분산 처리한다.
active/active 데이터 센터를 만들고자 함.

nat, proxy , gslb를 활용함.
대외계 가동률 100% 하고 싶다고 함.

 

기존 구조는 어떤 문제점을 갖고 있는가?
백본에서 기관 서버 ip를 직접 라우팅 함으로써 설정 복잡 관리 까다롭.
서버 ip 삭제해서 장애, ip 중복으로 인한 장애.
데이터 센터마다 별도의 전용선 가져가는 방식으로 진행.
전용구간 장애 시 힘들다!

 

NAT를 적용해 보자!
SNAT, DNAT를 적용

백본은 기관 서버 ip를 직접 하지 않고 dnat 대역을 라우팅 하자!


proxy 활용
L4 L7 스위치인 로드밸런서를 활용하기로 함.
리버스 프록시.

서버 상태 확인하고 정상서버로만 라우팅함.
대외계 아웃바운드에 적용함

서버는 프록시로 통신하고 프록시는 방화벽에 nat를 통해서 기관과 통신.
프록시 헬스체크를 통해 전용선구간 or 그냥 구간 중에서 하나 에러 시 전환 가능.

nat - 복잡한 라우팅을 단순화, 기관 아이피 해결
프록시 -서버 상태 체크 로드밸런싱, 응답 속도를 측정
gslb - 서버 간의 통신을 도메인 기반으로 변경하고 프록시 장비의 장애를 감지하여 우회 가능.

 

미처 알지 못했던 Kernel까지 Observability 향상시키기


 

 

누마 활용한 모니터링?

cpu, memory, device io를 사용할 때 kernel이 이걸 분배해 주니까 쉽지가 않다.

kernel이라는 애가 black box 형태로 존재한다.
EBPF를 통해서 이걸 한 꺼풀 벗겨내 주는 것 같다.

 

ebpf 주소

 

eBPF - Introduction, Tutorials & Community Resources

eBPF is a revolutionary technology that can run sandboxed programs in the Linux kernel without changing kernel source code or loading a kernel module.

ebpf.io

 

메모리를 읽고 사용하는 stalled라는 기다리는 시간이 포함되기 때문에 memory io를 잘 트레이싱할 필요가 있다.

malloc으로 가상 메모리 확보하고 실제 메모리를 할당하는 방식.

page fault가 포인트이고 EBPF를 통해서 page fault를 분석하는 게 중요함.

numa는 무어에 법칙을 통해서 성능은 쭉 올라가나 cpu와 memeory에 대한 버스 성능은 올라가지 않았다.
채널을 활용해서 이걸 극복하는 게 누마 아키텍처이다.

remote access에서 홉이 추가되어 사이클이 더 필요하며 remote access가 아키텍처에 얼마나 영향을 주었는지 찾을 필요가 있다.
numa migration system call으로 q초에 10~50 ms 시간을 cpu 스케줄러가 소모한다.

그렇다면 컨테이너 기반에서 어떻게 해결할까?


cpuset_cpu
cpuset_memory
많은 클러스터에 이걸 일일이 설정하기엔 어렵다.

k8s에서 할 수 있는 방법은

cpu pinning
메모리 할당이 numa1에서도 일어날 수 있음, cpu 피닝 된 코어 이상 못쓴다.

memory pinning 
단점  cpu 가 소켓을 왔다 갔다 할 수 있다.

socket pinning 전략
numa 0번에 cpu ~ 10까지 전부 할당.
remote access 도 잘 나오지 않을 것 같음.

cluster 전체 cpu 사용율 13% 성능 향상.
cloudflare 사의 ebpf exporter를 통해서
numa 관련 metric 수치를 뽑아낼 수 있다.

 

Redis latency 이상현상 파악


이 세션은 20~50ms 가 간헐적으로 튀는 것에 대한 개발자 특유의 광기, 내지 집요함이 보인 세션이었다...

 


20~50ms 튀는 게 생김.

tcpdump부터 뜨면서 application 보내는 쪽, redis 받는 쪽 체크.

redis에서 보내고 application에서 받았을 때 늦게 도착.
네트워크 장비에는 아무런 문제가 없고
네트워크 장비와 애플리케이션 사이에서 좀 늦었다.

perf trace를 활용해서 확인.
perf 대신에 ebpf를 활용해서 분석.

bcc tool을 써보자.
fuction latency를 확인 가능.
각각의 함수 체크 시 느린 함수가 없었음.

pixie 
system call read를 통해서 모니터링함.
느리다는 것은 알 수 있음 원인은 힘듦.

k8s iptable -> ipvs, calico policy(iptable)?

네트워크 인터페이스 넷필터 얼마나 타는지 확인하고 싶었음
nflatency,py 

ip table에 걸려있는 hook 들의 종류 등을 측정 가능함.
느린 값이 안 나옴..
필터는 안 나오나 보다.

softirq로 네트워크 irq를 측정함.
timer_softirq가 왜 느리지?
timer 쪽 소스코드 내에서 체크 로직 넣어서 돌림

규모가 큰 경우 estimation이 문제가 생김

1. kernel 버전업 후 skip 결정
2. kernel patch를 해서 skip과 동일하게 전부 덮어버리던지
3. cillium ebpf로 변경하는 방법.

 

보상 트랜잭션으로 분산 환경에서도 안전하게 환전하기


 

Saga에 대한 블로그 글을 조금씩 준비하는 중이었고.
이전 Saga 관련 발표내용을 다른 컨퍼런스에서도 본 적이 있었기 때문에 어떤 식으로 발표하실지 기대가 많이 된 세션이었다.

 

단일서버 단일 디비 모놀리식 구조의 기간계
기간계를 도메인으로 분리된 msa 환경으로 변화 중이다.
신규 상품의 경우에는 디비 분리까지 진행한 msa 환경에서 개발 진행 중이다.

원화 계좌서버 -- 오라클
외화 계좌 -- mysql
위와 같이 서버와 디비가 분리되어 있다면 트랜잭션 원자성 처리가 쉽지 않다.
환전의 원자성을 보장하기 위해 분산 트랜잭션이 구현되어야 한다.

 

분산 트랜잭션 구현법으로

2 phase commit과 saga에 대해서 간략하게 설명을 진행한다.


환전서버 및 환전 상태 관리하기 위한 환전 서버가 있어야 하고 추적이 필요하기 때문에 오케스트레이션 방식으로 했다고 한다.

자 그럼 saga를 활용해서 어떻게 환전처리를 했을까? 🤔

환전 서버가 원화 계좌 서버로 1300 출금 요청
외화 계좌로 1달러 입금 요청.
입출금 중에 하나가 실패한다면?

실패는
1. 정상적 실패 - 잔액부족, 계좌 해지
2. 비정상적 실패 - 서버 에러, 네트워크 에러, 타임아웃

출금 후 입금 시 실패한다면 면
원화 계좌에 보상트랜잭션 처리를 해줘야 함.

출금부터 진행을 하게 되는데 왜 출금부터 진행을 하는가?

입금부터 한다면 외화 계좌에서 그사이에 결제처리가 된다면 -가 되기 때문에
환전 saga는 출금부터 이루어져야 한다.

http vs messaging

대부분의 saga는 message를 활용하기는 하지만,

입금과 출금은 http를 활용했다.


유저가 환전이 즉시 완료되기를 기대함. 

타임아웃 구현이 필요함.

보상트랜잭션인 출금 취소는 message로 활용했는데,
출금 취소는 마지막 과정이고.
유저가 기다릴 필요가 없기 때문이다.(비동기)
출금 취소에 대한 에러 핸들링을 하기가 싫은 것도 있었다.

에러 핸들링

환전서버 -- 출금 요청 --> 원화 계좌 서버.
환전 서버 -- 출금 결과 확인 --> 원화 계좌 서버.

입금도 마찬가지다.
프로듀서가 메시지 발생하면 브로커를 전달해서 컨슈밍 한다.
지연값을 넣어서 발행하면 카프카 스케쥴러에 들어감
그리고 컨슈머가 특정 시간 뒤에 가져간다.

출금 결과 확인실패 시 카프카 메시지 브로커를 통해서 30초 정도를 지연한 뒤에 출금 결과 확인 재시도할 수 있다.
원화 계좌 서버가 회복할 시간을 준다.
환전서버가 죽어서 메시지 발행조차도 못하고 죽으면\
bath를 통해 재처리.

출금이 성공하고 환전 서버가 죽는다면
batch를 통해서 재처리를 한다.

원화 계좌가 출금 처리를 하다가 에러가 나면 CDL 컨슈머 데드레터를 브로커가 dl서버를 통해서 다시 broker에게 메시지 발행 하도록 한다.

transactional messaging 처리 방법
PDL processor dead letter를 활용 중임.
pdl message broker --> dl --> message borker

모니터링은?


오케스트레이션에서 state machine

환전 시작 후 출금 실패
환전 시작 후 출금 성공

상태값을 insert 해서 본다.

ETL을 통해서 정보게 데이터베이스를 바라보고 있음
batch를 통해서 입금만 되었거나 출금만 된 계좌를 확인할 수 있음.

확장성에도 이점이 있는데.
원화 계좌 서버, 외화 계좌 서버가 메시지 발행해서 회계서버 와 연계
saga를 활용하여 추가적인 확장에 용이하게 되었다
카드의 경우에도 saga서버를 통해서 작업이 가능하다.

토스뱅크가 차세대를 하지 않는 이유- 지속 가능한 마이그레이션 전략


 


대부분 차세대 프로젝트는 워트풀 방법론 활용.
배포가 한꺼번에 진행되고 유연성이 부족함.

기존 차세대는 빅뱅식에 가깝다.
요구사항 정의 설계 개발 테스트 하다가 추가 요구사항 발생하고 이런 방식으로 진행됨.

strangler fig pattern을 활용하여 은행 시스템을 안전화게 전환 해보자. 

strangler fig pattern 
기존 시스템을 점진적으로 새로운 시스템으로 대체하는 전략.


모놀리식 코어뱅킹 시스템을 micro service로 전환 중.
유즈케이스 단위로 단위를 독립적으로 분리하기 시작.

마이그레이션 사이클


첫 번째 대상선정 - 어떤 걸 microservice로 바꿀지?

대출 상환 도메인 - 돈을 빌렸을 때 언제 어떻게 값아야 하는지 설명.
핵심 도메인일수록 사이드이펙트가 크기 때문에 복잡도와 영향도가 적은 애들부터 변경 시작.

두 번째 분석

연역적 분석
일반적인 원칙이나 이론을 바탕으로 구체적인 사례나 결론을 도출.
도메인 분석, 대전제 확인

귀납적 분석
구체적인 사례나 데이터를 통해 일반적인 원칙이나 이론을 도출.
소스코드와 데이터 흐름, 함수 호출 분석등.

정적 분석 함수 간의 호출관계를 파악하여 시스템 전체 구조 확인
동적분석 카프카를 활용하여 메서드 사용빈도등을 확인함.

업무 매뉴얼을 통해 연역적 분석 진행함.
연역적 분석으로 대전제 설정, 귀납적 분석으로 대전제 검증을 진행함.

세 번째 단계는 설계
문석 및 설계 문서 작성 & 리뷰
마이그레이션에 핵심 가이드로 작용함.

데이터를 도메인 로직에 캡슐화? 너무 빨리 지나감..

테스트 코드 작성을 통해서 도메인 안정성과 신뢰성을 확보한다.

도메인 문서화를 통해서 지속적인 관리, 및 중요.
담당자가 바뀌더라도 새로운 사람이 빠르게 파악하고 최적화된 로직을 개발할 수 있기 때문.

글뿐만 아니라 다이어그램과 같은 시각적인 것을 많이 활용하자.

구현, 검증, 리팩토링 과정.
기존 로직과 100% 같은 출력값을 반환해야 부수효과를 막을 수 있음.
분할 정복을 하기 위해서 컴포지트 패턴을 활용한다.

분할정복 과정
레거시는 모놀리식을 호출하게 됨.
leaf 노드부터 하나하나 전부 작성 후 불필요한 로직들을 리팩터링 하여 노드들을 제거하는 방식?
리팩토링 단계가 각각 존재함.

디스패처를 통해서 레거시 실행 후 반응은 유저에게 바로 전달됨.
그리고 리팩 한 모듈을 병렬 진행.

어드민을 통해서 잘못된 로직이 포함되었는지 확인 가능
검증에 성공한다면 다시 대상 선정
검증 실패 시 분석하는 것부터 다시 시작.

 

대규모 사용자 기반의 마이데이터 서비스 안정적으로 운영하기


 

 


api 호출이 임계치를 넘어가면 제공해 주는 기관이 좀 힘들 수 있다.
트래픽이 몰리면 좀 차단해서 제공기간이 회복할 수 있게 해줘야 하나?

Resilience4 j를 통해서 기관별로 서킷구현을 해두었다.
그러나 서버단위로 서킷이 적용되기 때문에 장애 대응을 하기에 충분하지 않았다.

모든 서버가 a은행으로 가는 과정이 발생하게 된다.
그러나 하나만 요청을 실패한다.
실패율은 10% 인데 전체 서버가 서킷이 걸릴 수 있다.
서버마다 서킷에 상태가 다르기 때문에 시스템이 일관적인 동작을 못하게 된다.

그래서 코디네이터 시스템을 개발하기로 하였다.
하나는 마이데이터 서버에 구현하는 것, 다른 하나는 별도에 서버에 구현하는 것.

별도의 서버에 구현하기로 한 이유는?
장애포인트 일원화
유연하고 확장 가능한 시스템.

mydata서버가 뜨기 전에 coordinator에게 서버 id를 받음
카프카 통해서 mydata 서버가 결과를 kafka에게 메시지로 줌
coordinator 서버가 메시지 확인한 뒤 실패율이 일정이 넘는 케이스에 한해서 서킷을 열어줌.

하지만 특정 마이데이터 서버가 느려지면
게이트웨이랑 네트워크 장비들을 통해서 패킷전달을 하기 때문에
전체를 점유하고 있어서 문제가 될 수 있음.

websocket 또는 polling을 활용하자.
toss app을 열만 webscoket 서버를 통해서 connection을 맺게 됨.
긴 자산 등록 api 요청을 시작함.


mydata서버는 네트워크 정보, api gateway 쪽에 eraly return을 통해서 점유를 해지하고
제공기관에 대한 반환값을 websocket 서버에  동적으로 전달해서 동적으로 처리함.
3300 -> 58ms의 점유시간 감소.

유저의 액션에 의한 유저 호출
일주일에 한 번 토스에 의한 배치 호출.
7일 동안 api 호출을 균일하게 할 수 있을까?

유저 호출이 많은 날은 배치 호출을 낮추고 유저 호출이 낮은 날은 배치 호출을 높임.
배치호출이 활발할 경우 4만 개를 한 번에 가져올 수 있게 되고 슬로 쿼리가 발생함.

코루틴이랑 코루틴 채널을 활용함
배치처리도 7일에 걸쳐서 균일하게 처리하려고 노력했다.

 

컨퍼런스 느낀 점


 

좋았던 점

 

올해 aws , spring , josh long 세 곳 컨퍼런스를 다녀왔는데.

aws는 생각보다 좀 별로였고, josh long 은 q&a가 좀 더 좋았다.

spring camp는 발표도 괜찮았고 q&a도 너무 좋았다.

slash24 만의 장점이라면.

 

1. 금융 도메인에 대한 해결 공유.

아무래도 도메인적 특성이 강한 것 같다.

금융 도메인에 종사하시는 개발자들, 그리고 큰 레거시를 개선하고 있는 문제를 다루고 있는 분들에게 많은 개선 아이디어와 좋은 경험들이 공유될 수 있는 자리인 것 같다.

 

2. 발표 내용에서 느낄 수 있는 문제 해결에 대한 집요함

문제를 인식하고 해결해 나가는 방법에서 촘촘하고 집요한 부분들이 많이 느껴져서 놀라웠다.

 

 

아쉬운 점

 

1. 짧은 세션 발표 시간

세션별 발표가 20분으로 상당히 타이트했다.

발표하는 세션 주제가 상당히 괜찮고.

기존 구조 및 문제 인식 -> 해결 -> 개선된 성능 or 추가적인 모니터링방안 -> or 향후 개선사항

위와 같이 발표의 진행방식도 깔끔하나.

내용과 진행방식에 비해서 발표 시간이 절대적으로 짧기 때문에 아무래도 발표하시는 분들이 빠르게 진행하시는 게 좀 아쉬웠다.

 

세션발표 시간을 넉넉하게 늘려서 발표자 분들이 발표하시는 데 있어서 좀 더 여유를 가질 수 있는 환경이 되었으면 좋겠다는 생각을 해보았다.

(코엑스 홀을 추가 대관을 해서 세션 발표 시간을 좀 더 늘리고 세션의 양을 좀 더 늘려서 참가자들이 보다 나은 것을 찾아서 듣는 방식이 괜찮다고 생각이 들었다.)

 

2. q&a가 존재하지 않는다.

그렇다 발표시간도 짧은데 q&a가 어디 있으랴.

세션사이에 쉬는 시간도 타이트하고 세션 발표시간도 짧아서인지 발표자에게 q&a 하는 시간이 존재하지 않는다.

반응형

'Etc' 카테고리의 다른 글

GPT-4 의 등장  (2) 2023.03.15

댓글