분류 전체보기 197

[Design Doc] Transactional Outbox Pattern — Kafka 직접 발행의 한계와 설계 (7주차 · 6팀 · 조수현)

TL;DRKafka에 직접 발행하면 트랜잭션 커밋과 Kafka 발행 사이의 원자성을 보장할 수 없다. Outbox 테이블을 경유하는 방식으로 At Least Once 발행을 보장했고, partition-offset 기반 멱등성 키의 한계를 발견해 outboxId 기반으로 진화시켰다.Introduction & GoalsContext / Background좋아요, 조회, 주문 이벤트를 다른 시스템(commerce-streamer)으로 전파해야 했다. 처음엔 서비스 로직 안에서 직접 kafkaTemplate.send()를 호출하는 방식을 고려했는데, 트랜잭션 커밋 직후 Kafka 발행 직전에 애플리케이션이 죽으면 이벤트가 유실된다는 문제가 있었다.// 문제: 커밋 후 send 전에 죽으면 이벤트 유실@Tran..

카테고리 없음 2026.07.03

[Design Doc] PG 외부 연동 장애 대응 설계 (6주차 · 6팀 · 조수현)

TL;DRFeignClient로 PG를 호출하는 결제 시스템에서 Timeout + Retry + CircuitBreaker 조합을 적용해 PG 장애가 전체 서비스로 번지는 Cascading Failure를 차단했다. 타임아웃/CB Open 시 PENDING 유지 + 30초 배치 복구로 상태 정합성을 보장한다.Introduction & GoalsContext / Background결제 요청 시 우리 서버가 PG(Payment Gateway)를 FeignClient로 동기 호출한다. PG는 외부 시스템이므로 응답 지연이나 장애를 제어할 수 없다. Tomcat 스레드 풀(기본 200개)은 PG 응답을 기다리는 동안 블로킹 상태로 묶이며, 스레드가 고갈되면 결제와 무관한 상품 조회나 주문 생성까지 503을 반환..

카테고리 없음 2026.06.26

[Benchmark] MySQL 인덱스 전략 비교 — 좋아요 순 상품 목록 최적화 (5주차 · 6팀 · 조수현)

TL;DR상품 목록 API의 좋아요 순 정렬 성능을 확보하기 위해 13개 시나리오에서 인덱스 전략을 실측 비교했다.brand_id 단일 인덱스만으로 풀스캔 대비 100ms → 0.1ms(약 1,000배) 를 달성했으며,읽기 성능이 사실상 동일한 반정규화 vs 분리 테이블 중동시 쓰기의 락 경합 격리를 이유로 product_like_view 분리 테이블을 선택했다.Question — 무엇을 비교했는가결정해야 했던 것브랜드별 상품 목록을 좋아요 순으로 정렬하는 API에서 두 가지 질문을 동시에 풀어야 했다.인덱스 전략: 인덱스 없음 / 단일(brand_id) / 복합(brand_id, like_count DESC) / 커버링 중 어느 수준까지 필요한가?like_count 저장 구조: products 테이블에..

카테고리 없음 2026.06.22

[Design Doc] 쿠폰 테이블 설계 (6팀, 4주차, 조수현)

TL;DRCouponTemplate과 UserCoupon을 분리하고, isActive(신규 발급 차단)와 isBlocked(기존 쿠폰 전량 차단)를 별도 책임으로 설계했다. CouponStatus는 DB에 저장하지 않고 조회 시점에 계산한다.Introduction & GoalsContext: 쿠폰 정책(할인율, 유효기간)과 발급본(소유자, 사용 여부)을 하나의 테이블로 관리하면 정책 변경 시 발급된 전체 row가 영향을 받는다. 100만 명이 발급받은 쿠폰의 할인율이 잘못됐으면 100만 row를 UPDATE해야 한다.Goals: 정책 변경이 기존 발급 쿠폰에 소급 적용되지 않는 구조. 운영자가 신규 발급만 막거나, 기존 쿠폰 사용까지 막거나, 두 가지를 독립적으로 제어할 수 있을 것.Detailed De..

카테고리 없음 2026.06.12

[Design Doc] 레이어드 아키텍처 설계 — 4개 레이어, 컴포넌트, 실제 구현 (3주차 · 6팀 · 조수현)

TL;DR4개 레이어(interfaces, application, domain, infrastructure)로 구성된 레이어드 아키텍처를 적용했다.의존 방향은 interfaces → application → domain ← infrastructure 단방향으로 강제하고,DIP(의존성 역전 원칙)로 domain이 Spring/JPA/BCrypt 같은 인프라 기술을 모르는 구조를 만들었다.Introduction & Goals커머스 백엔드 API를 설계할 때 두 가지 문제를 피하고 싶었다.기술 의존 전파: Spring Security, JPA 같은 인프라 기술이 비즈니스 로직에 직접 침투하는 것책임 불명확: "이 코드는 어느 레이어에 있어야 하나?"라는 질문에 명확히 답할 수 없는 구조레이어드 아키텍처 + D..

카테고리 없음 2026.05.29

[Challenge Story] 주문·결제 동시성 제어 — 6개 문제를 연쇄 발견한 설계 여정 (2주차 · 6팀 · 조수현)

TL;DR주문/결제 시스템에서 동시성 문제를 하나씩 해결할 때마다 새로운 문제가 연쇄적으로 드러났다.SAGA 패턴 → 취소 시 Lost Update → 데드락 → 이중 취소까지 6개 문제를 차례로 발견하고,SELECT FOR UPDATE와 정렬 기반 락 획득 순서로 모두 해결했다.문제 1: 결제 실패 중 새 주문 → 트랜잭션 분리로 보상 범위 명확화 (보상 자동 실행은 미구현) ↓문제 2: 주문 취소 시 재고 Lost Update → 취소에도 SELECT FOR UPDATE 추가 ↓문제 3: 여러 상품 주문 시 데드락 → productId 오름차순 정렬로 해결 ↓문제 4: 이중 취소 요청 → Order에 SELECT FOR UPDATE 추가 ↓문제 5: PENDING 방치 → 배치 ..

카테고리 없음 2026.05.22

TDD와 DDD로 처음 개발해보며 얻은 것들

이론으로만 알던 TDD와 DDD를 loopers에서 직접 적용하면서 "왜 이렇게 해야 하는가"를 몸으로 깨달은 기록.TDD 방법론은 무엇인가?TDD란 Test Driven Development의 약자로 '테스트 주도 개발'이다. 소프트웨어 방법론으로 작은 단위 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현한다. TDD의 개발 절차에는 Red -> Green -> Refactor를 반복하면서 Red 단계에서는 테스트 케이스에 맞는 실패하는 테스트 코드를 먼저 작성하고, Green 단계에서는 테스트를 성공시키기 위한 최소한의 코드를 작성한다. 마지막으로 Refactor 단계에서 중복 코드 제거, 일반화 등 리팩토링을 한다. 이 과정에서 중요한것은 실패하는 테스트 코드를 작성하기..

[Spring Boot] JWT를 이용한 인증/인가 구현하기(Spring Security X)

JWT를 사용하기 위한 파일FilterConfig.java@Configuration@RequiredArgsConstructorpublic class FilterConfig { private final JwtUtil jwtUtil; @Bean public FilterRegistrationBean jwtFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new JwtFilter(jwtUtil)); registrationBean.addUrlPatterns("/*"); // 필터를 적용할 URL 패턴을 지정합니다. ..

[Spring Boot] 스레드(Thread)

스레드란?스레드란 프로그램에서 실행되는 작업의 최소 단위입니다. 예를 들어 API를 호출하면 Spring에서 스레드가 요청을 처리합니다.여기 한 식당이 있습니다. 그 식당에는 종업원(Thread) 이 있습니다. 각각의 종업원은 손님(Client)들에게 주문(request)을 받고 주방(Spring MVC) 에서 음식(response) 이 완성이되면 음식을 손님에게 음식을 전달해 줍니다.   성능이 좋은 서버란?1. 하나의 스레드를 극한의 효율로 사용하기(싱글 스레드), 비동기 방식과 non-blocking방식을 사용 -> Node.js2. 스레드를 여러개 사용하기(멀티 스레드), 비공기 방식과 non-blocking 방식을 사용 -> Spring  동기와 비동기동기: 동기 방식에서는 작업이 순차적으로 진..

[Spring Boot] Spring Security를 이용하여 인증인가 구현하기

Spring Security란?Spring Security는 인증, 인가를 구현하는 데 도움을 주는 Spring의 프레임워크입니다.Spring Security를 이용하면 전에 구현했던 어노테이션을 만드는 과정도 매우 쉽게 구현할 수 있습니다. 이전에 JWT를 이용한 인증인가 [Spring Boot] JWT를 이용한 인증/인가 구현하기(Spring Security X)JWT를 사용하기 위한 파일FilterConfig.java@Configuration@RequiredArgsConstructorpublic class FilterConfig { private final JwtUtil jwtUtil; @Bean public FilterRegistrationBean jwtFilter() { FilterRegistr..