무거운 트랜잭션, 이벤트로 가볍게 만들기
2.8초짜리 트랜잭션 주문 생성 API의 응답 시간을 측정했더니 2.8초가 나왔습니다. 트랜잭션 안에서 일어나는 일들을 나열해봤습니다. 주문 생성 트랜잭션 (2.8초) ├── 재고 차감 (150ms) - 핵심 비즈니스 ├── 주문 생성 (100ms) - 핵심 비즈니스 ├── 쿠폰 사용 처리 (200ms) - 부가 작업 ├── 결제 데이터 전송 (2...
2.8초짜리 트랜잭션 주문 생성 API의 응답 시간을 측정했더니 2.8초가 나왔습니다. 트랜잭션 안에서 일어나는 일들을 나열해봤습니다. 주문 생성 트랜잭션 (2.8초) ├── 재고 차감 (150ms) - 핵심 비즈니스 ├── 주문 생성 (100ms) - 핵심 비즈니스 ├── 쿠폰 사용 처리 (200ms) - 부가 작업 ├── 결제 데이터 전송 (2...
문제: PG 장애가 전체 주문을 멈추게 한다 PG(Payment Gateway) 시스템이 간헐적으로 응답이 느려지는 상황이 발생했습니다. 결과는 예상보다 심각했습니다. PG 응답을 기다리는 스레드들이 쌓이면서 전체 주문 API가 응답 불능 상태가 됐습니다. PG 하나의 장애가 주문 서비스 전체를 마비시켰습니다. 단계적 해결: Timeout → R...
문제 정의 상품 목록 조회 API가 느렸습니다. 10만 건의 데이터를 기준으로 브랜드별 가격 범위 필터링 + 정렬 + 페이징을 처리하는데 체감상 느리다는 피드백이 있었습니다. 측정을 시작했습니다. 현실적인 테스트 데이터 생성 성능 테스트는 실제 데이터와 유사한 분포로 해야 의미 있습니다. -- 10만 건 데이터 생성 프로시저 DELIMITER ...
주문 기능에서 동시성 문제 주문 기능을 구현하다 보면 세 가지 도메인에서 동시성 이슈가 발생합니다. 재고 (Product): 동시에 10명이 마지막 1개를 주문하면? 포인트 (Point): 동시에 여러 결제가 같은 포인트를 차감하면? 쿠폰 (Coupon): 동시에 여러 사람이 같은 쿠폰을 사용하면? 처음에는 세 도메인 모두 비관적 ...
DDD 개념 정리 처음에는 Entity, VO, Domain Service를 구분하는 게 이론적인 개념 정리 정도로만 느꼈습니다. 실제 코드에 적용해보니 설계가 달라졌습니다. Entity 고유한 식별자가 있습니다 (id) 시간이 지남에 따라 상태가 변합니다 같은 id를 가지면 동일한 객체입니다 @Entity public class...
요구사항만으로는 부족했다 새로운 서비스 설계 과정에서 요구사항만 정리하면 충분하다고 생각했습니다. - 사용자는 상품을 주문할 수 있다 - 주문 시 재고가 차감된다 - 쿠폰이 있으면 할인이 적용된다 - 포인트로 일부 금액을 결제할 수 있다 문서로 정리하고 바로 구현에 들어갔습니다. 그런데 구현 단계에서 문제가 생겼습니다. 구조와 역할이 불...
통합 테스트인데 실제 DB를 전혀 검증하지 않았다 도메인 통합 테스트를 작성하던 중 뭔가 이상하다는 생각이 들었습니다. 서비스 레이어 테스트인데 Repository를 mock()으로 처리하고 있었습니다. // 변경 전: 이게 정말 통합 테스트인가? @ExtendWith(MockitoExtension.class) class PointServiceTe...
처음엔 왜 이렇게 복잡하게 만들었나 싶었습니다 과제 템플릿 프로젝트가 Facade 패턴으로 구성되어 있었습니다. Service 하나에 다 넣으면 되지 않나? 그래서 멘토한테 직접 물어봤습니다. 돌아온 비유가 기가 막혔습니다. “검지 서비스, 중지 서비스, 약지 서비스 — 각각 손가락을 펴는 순수한 서비스들이 있다. 이게 순수한 도메인 비즈니...