테스트란? TDD 관점에서 테스트는 요구사항에 대한 명세. 주어진 상황에서 객체(혹은 서버)에게 요청을 보냈을 때 기대하는 결과 혹은 과정에 대한 명세. 기대하는 결과를 명세: 특정 Input에 특정 Output 약속 ex) 평균값 메소드는 (1,2,5) → (3)를 테스트 기대하는 행동 명세: A메소드 호출은 B,C,D를 2번씩 호출하는 것을 약속 💡 테스트는 요구사항을 구현한 동작에 대한 검증 아닌가? 테스트를 작성하는 동기의 차이라고 생각합니다. 구현한 코드가 원하는 대로 동작하고 다른 코드의 변화에 의해 테스트가 작성된 코드가 영향을 받지 않는 것에 테스트의 목적을 둔다면, 테스트는 요구사항을 구현한 동작에 대한 검증으로 바라볼 수 있습니다. 반면, 요구사항을 구현하기 전, 사용자가 서비스에게 바..
📌 문제 상황 1. 즉각 요청-응답 프로세스는 외부 서비스와의 connection을 유지한 채 비관 lock을 잡기에, lock으로 인한 다양한 이슈가 외부 서비스로 전파될 위험 존재(ex. deadlock 발생시 connection도 대기) 2. 즉각 요청-응답 프로세스는 타행 이체(은행A→은행B 이체)를 2개의 API(이체 입금 요청 API, 이체 입금 완료 응답 API)로 구현하자는 은행 간 약속(프로토콜)을 무시하는 방법임. 📌 접근 방법과 해결과정 원인 분석 - 그림2 즉, 이체 입금 요청을 비동기로 처리하는 구조의 문제점 재파악. - 입금을 위해 비관 lock을 잡고 Network I/O를 하는 것이 가장 큰 문제라고 파악. - 특히 타행(이체 입금 역할)은 당행(이체 출금 역할)의 이체 내역..
목차 1. 간단 요약 2. 사전 지식 3. 문제 상황 4. 접근 방법과 해결 과정 Gap lock 분석 현 설계의 문제점 로컬 테스트로 검증 개선 방향 성능 테스트 5. 결과 6. 배운점 ✍️ 간단 요약 OutBox 데이터를 polling 하는 스케줄러가 읽기 연산을 할 경우, connection은 (마지막 레코드, 무한대) 범위에 gap lock을 겁니다(MySQL ver 8.0 innodb, Repeatable-read 기준). 그로 인해 이체 출금의 insert 쿼리가 병목이 되어 TPS가 낮게 나왔었습니다. Read Committed로 변경한 결과, gap lock의 해제를 기다리지 않고 insert할 수 있게 됐습니다. 이는 Mean Test Time 감소로 이어져 tps를 86%(66.6 → ..
목차 1. [문제 상황] 비동기가 너무 느린 현상 2. [원인 분석] 동기로 작동하는 경우(케이스) 존재 3. 이체 입금 요청 API 처리 방법별 장단점 4. API 로직 선정 및 테스트 5. 고민해봐야할 것 ✍️ 사전 지식 용어 당행 : 사용자로부터 이체 요청을 받고, 이체 입금을 진행하는 은행 타행 : 이체 과정에서 출금을 진행하는 은행 당행 이체 : 입금 은행과 출금 은행이 동일한 이체 타행 이체 : 입금 은행과 출금 은행이 다른 이체 OutBox 데이터 : 이벤트나 메시지를 DB에 있는 아웃박스에 저장해서 DB 트랜잭션의 일부로 발행하는 패턴을 Transactinal OutBOx라고 합니다. 서로 다른 서버의 트랜잭션을 관리하고 할 때, eventual consistency를 보장하기 위해 DB ..
목차 1. [문제 상황] 동기 보다 비동기가 느린 현상 2. [원인 분석] 로컬에서만 일어나는 NIO 3. [해결] 당행과 타행으로 테스트 서버 분리 4. 고민해봐야할 것 ✍️ 사전 지식 용어 당행 : 사용자로부터 이체 요청을 받고, 이체 입금을 진행하는 은행 타행 : 이체 과정에서 출금을 진행하는 은행 당행 이체 : 입금 은행과 출금 은행이 동일한 이체 타행 이체 : 입금 은행과 출금 은행이 다른 이체 OutBox 데이터 : 이벤트나 메시지를 DB에 있는 아웃박스에 저장해서 DB 트랜잭션의 일부로 발행하는 패턴을 Transactinal OutBOx라고 합니다. 서로 다른 서버의 트랜잭션을 관리하고 할 때, eventual consistency를 보장하기 위해 DB 테이블을 메세지 큐로 사용하는 방식을 ..
목차 1. 문제 상황 2. 요구 사항 분석 3. 스케줄링 전략 선정 테스트 환경 스케줄러 전략 간단 요약 스케줄러 전략별 장단점 스케줄러 전략 상세 설명 및 테스트 결과 스케줄러 전략 3번 선택 4. 개선 필요 사항 ✍️ 사전 지식 용어 당행 : 사용자로부터 이체 요청을 받고, 이체 입금을 진행하는 은행 타행 : 이체 과정에서 출금을 진행하는 은행 당행 이체 : 입금 은행과 출금 은행이 동일한 이체 타행 이체 : 입금 은행과 출금 은행이 다른 이체 OutBox 데이터 : 이벤트나 메시지를 DB에 있는 아웃박스에 저장해서 DB 트랜잭션의 일부로 발행하는 패턴을 Transactinal OutBOx라고 합니다. 서로 다른 서버의 트랜잭션을 관리하고 할 때, eventual consistency를 보장하기 위해..
목차 1. 개요 2. 서버가 다운되면 무슨 일이 일어날까? 기존 타행 이체 순차 다이어그램 서버 다운 가능 지점 3. Transactional Outbox Pattern 이벤트 발행 패턴 선정 아웃박스 패턴을 적용한 순차 다이어그램 서버 다운 check, 아웃박스 패턴을 적용한 순차 다이어그램 이체 입금 요청 API의 멱등성 4. 구현 ✍️ 개요 이체 기능을 설계하면 가장 신경 쓴 것은 데이터 정합성이였습니다. 키워드의 검색 횟수 같은 데이터는 정합성이 완전하게 맞춰질 필요가 없을 수 있습니다. 하지만 돈과 같은 경우는 1원이 없어지더라도 이는 결국 회사 혹은 고객의 돈이 없어지는 것 이기 때문에 큰 문제로 이어질 수 있습니다. 그렇다면 돈은 언제 없어질까요? 돈은 이체 하는 과정에서 해피케이스가 아닌 ..
목차 1. 프로젝트 소개 2. 프로젝트 개선 그래프 3. 트래픽의 개략적인 측정 4. 서버 인프라 구성 5. 문서화 ✍️ 프로젝트 소개 카카오 뱅크, 토스 뱅크, 케이 뱅크 등 은행 도메인의 돈통을 구현하는 프로젝트 입니다. 은행에서는 이자 적립, 예약 이체 등 여러 기능들이 있지만, 현 프로젝트에선 대용량의 트래픽이 발생하는 상황에서 '이체' 기능을 잘 수행할 수 있는 백엔드 개발을 중시했습니다. 데이터 정합성, 속도와 사용자 경험을 생각하며 이체 기능을 설계하고 구현했습니다. 서버에 장애가 일어나는 상황을 생각하며 데이터 정합성을 고려했고, 속도 관련 이슈를 해결하기 위해 nGrinder와 APM을 이용하여 객관적인 근거를 찾았습니다. 해결 방법을 찾을 때는 사용자 경험을 고려하며 기획과 Engine..
안녕하세요🙌! 개발자 갈레입니다! 이번 글에서는 야크의 털은 어디까지 깎아야할까(문제를 해결하기 위해 어느정도 깊이까지 공부해봐야할까)에 대한 저의 경험과 결론을 공유하려 합니다. 야크 털 깎기란 '목표한 일 하나를 하기 위해 연관된 작업들을 하다가 결국 원래의 목적을 잃고 완전히 관련 없는 작업을 하게 되는 것'입니다. 아래는 하나의 예시입니다! 나무를 베기 위해 도끼를 구했다. 도끼날이 너무 무뎌 날을 갈기 위한 돌을 구하려 한다. 그런데 어떤 마을에 정말 좋은 돌이 있다는 이야기를 듣는다. 그 마을에 가기 위해 야크를 구한다. 야크 털이 너무 길어서 털을 깎기 시작한다. 결론 결론부터 말하겠습니다! 저는 문제를 본래의 목적과 상관 없이 너무 깊이 파고드는 느낌이 들 땐 아래 질문 세가지를 던집니다!..