<feed xmlns="http://www.w3.org/2005/Atom"> <id>https://cwangg897.github.io/</id><title>기술블로그</title><subtitle>백엔드 개발자의 기술 블로그입니다. 개발하며 배운 것들을 기록합니다.</subtitle> <updated>2026-04-12T17:09:06+09:00</updated> <author> <name>Choi Wang Gyu</name> <uri>https://cwangg897.github.io/</uri> </author><link rel="self" type="application/atom+xml" href="https://cwangg897.github.io/feed.xml"/><link rel="alternate" type="text/html" hreflang="ko" href="https://cwangg897.github.io/"/> <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator> <rights> © 2026 Choi Wang Gyu </rights> <icon>/assets/img/favicons/favicon.ico</icon> <logo>/assets/img/favicons/favicon-96x96.png</logo> <entry><title>최종적 일관성과 트랜잭션 분리를 통한 외부 API 호출 격리: 주문/발급 아키텍처 구축기</title><link href="https://cwangg897.github.io/posts/transaction-separation-external-api/" rel="alternate" type="text/html" title="최종적 일관성과 트랜잭션 분리를 통한 외부 API 호출 격리: 주문/발급 아키텍처 구축기" /><published>2026-03-07T00:00:00+09:00</published> <updated>2026-03-24T17:46:01+09:00</updated> <id>https://cwangg897.github.io/posts/transaction-separation-external-api/</id> <content type="text/html" src="https://cwangg897.github.io/posts/transaction-separation-external-api/" /> <author> <name>Choi Wang Gyu</name> </author> <category term="Spring" /> <category term="Architecture" /> <summary>개요 기프티콘 주문 시스템을 구축하며 가장 큰 고민은 “우리 시스템의 DB 트랜잭션과 외부 API(KT 기프티쇼)의 상태를 어떻게 동기화할 것인가?” 였습니다. 네트워크 지연이나 외부 서버 장애가 우리 서비스의 전체 장애로 번지지 않도록 아키텍처를 개선한 과정을 공유합니다. 문제 상황: 모든 것을 하나의 트랜잭션으로 묶었을 때의 리스크 초기 설계는 단순했습니다. 모든 과정을 하나의 @Transactional로 묶어 원자성(Atomicity)을 보장하려 했습니다. 기존 구조 (Before) 다음은 초기 구조(단일 트랜잭션 + 외부 API 호출 포함)입니다. @Transactional public GifticonOrderCreateResponse execute(GifticonOrderC...</summary> </entry> <entry><title>WebSocket 채팅 안정화 개선기: Redis Pub/Sub 재설계와 운영 지표 검증</title><link href="https://cwangg897.github.io/posts/chat-improve/" rel="alternate" type="text/html" title="WebSocket 채팅 안정화 개선기: Redis Pub/Sub 재설계와 운영 지표 검증" /><published>2026-02-09T00:00:00+09:00</published> <updated>2026-02-09T00:00:00+09:00</updated> <id>https://cwangg897.github.io/posts/chat-improve/</id> <content type="text/html" src="https://cwangg897.github.io/posts/chat-improve/" /> <author> <name>Choi Wang Gyu</name> </author> <category term="Spring" /> <category term="Architecture" /> <summary>개요 먼저 저희 서비스는 고객이 업무 요청서를 통해 이루미와 매칭된 뒤, 서비스 내 채팅을 중심으로 업무를 진행, 관리하는 구조입니다. 하지만 운영 과정에서 다음 문의가 반복적으로 발생했습니다. 이루미 응답 지연 시 대응 방법 문의 및 환불 요청 결과물 확인 경로 문의 업무 시간 연장 방법 문의 즉, 채팅이 단순 메시지 확인 역할에 머물러 있었고, 실제 업무 관리와 실시간 소통을 안정적으로 지원하지 못하는 한계가 있었습니다. 이 문제를 해결하기 위해 채팅 기능 개선을 시작했습니다. 화면 요구사항에 맞춰 API를 정리하는 동시에, 기존 실시간 메시징 구조(WebSocket + Redis Pub/Sub)의 불안정성도 함께 개선했습니다. 이번 작업의 목표는 “더 빠른 시스템”이...</summary> </entry> <entry><title>Redisson 세마포어로 선착순 매칭 수락 병목 해소하기</title><link href="https://cwangg897.github.io/posts/redisson-permit-expirable-semaphore/" rel="alternate" type="text/html" title="Redisson 세마포어로 선착순 매칭 수락 병목 해소하기" /><published>2025-10-31T00:00:00+09:00</published> <updated>2026-04-12T17:08:48+09:00</updated> <id>https://cwangg897.github.io/posts/redisson-permit-expirable-semaphore/</id> <content type="text/html" src="https://cwangg897.github.io/posts/redisson-permit-expirable-semaphore/" /> <author> <name>Choi Wang Gyu</name> </author> <category term="Spring" /> <category term="Architecture" /> <summary>개요 프리랜서 매칭 서비스에서 고객의 업무 요청이 올라오면, 여러 프리랜서가 같은 건을 선착순으로 수락합니다. 이때 트래픽이 순간적으로 몰리면 동일한 업무 요청 행(Row)에 락 경합이 집중되면서 응답 지연이 급격히 증가했습니다. 이번 글에서는 DB 락에만 의존하던 구조를 Redis 기반 분산 세마포어(Redisson RPermitExpirableSemaphore)로 보강해 트랜잭션 진입 전 부하를 차단하고, DB에서는 최종 정합성만 검증하도록 바꾼 과정을 정리합니다. 문제 상황: 단일 Row 락 경합으로 인한 병목 기존 구조는 아래와 같았습니다. 선착순 시나리오 특성상 수백 명이 같은 업무 요청에 동시에 접근하면 대부분의 요청이 DB 락 대기열에서 대기하게 됩니다. 결과적으로 다음 문...</summary> </entry> <entry><title>외부 API 장애를 격리하는 Transaction Outbox + 멱등 비동기 파이프라인 구축기</title><link href="https://cwangg897.github.io/posts/transaction-outbox-idempotent-async-messaging/" rel="alternate" type="text/html" title="외부 API 장애를 격리하는 Transaction Outbox + 멱등 비동기 파이프라인 구축기" /><published>2025-09-15T00:00:00+09:00</published> <updated>2025-09-15T00:00:00+09:00</updated> <id>https://cwangg897.github.io/posts/transaction-outbox-idempotent-async-messaging/</id> <content type="text/html" src="https://cwangg897.github.io/posts/transaction-outbox-idempotent-async-messaging/" /> <author> <name>Choi Wang Gyu</name> </author> <category term="Spring" /> <category term="Architecture" /> <summary>개요 업무 매칭 완료, 업무 제안 같은 주요 비즈니스 이벤트가 발생하면 알림톡 API를 호출해야 했습니다. 초기에는 이벤트를 받아 비동기로 외부 알림 API를 호출하는 구조였지만, 장애 상황에서 전송 실패를 안정적으로 복구하지 못하는 문제가 있었습니다. 이번 글에서는 Transaction Outbox 패턴으로 비즈니스 트랜잭션과 알림 발송을 분리하고, 워커 기반 재시도와 DB 제약조건을 이용해 멱등성이 보장된 비동기 메시징 파이프라인을 구축한 과정을 정리합니다. 문제 상황: 비동기였지만 신뢰성은 부족했던 구조 기존 구조는 다음과 같았습니다. 정상 시에는 동작했지만, 외부 API 장애나 네트워크 문제에서 취약했습니다. 외부 알림 API 장애/타임아웃 발생 시 실패 이벤트 유실 가능 ...</summary> </entry> <entry><title>Redis Sorted Set으로 매칭(추천) 성능 최적화하기</title><link href="https://cwangg897.github.io/posts/redis-sorted-set-freelancer-recommendation/" rel="alternate" type="text/html" title="Redis Sorted Set으로 매칭(추천) 성능 최적화하기" /><published>2025-04-11T19:09:00+09:00</published> <updated>2026-04-05T18:28:42+09:00</updated> <id>https://cwangg897.github.io/posts/redis-sorted-set-freelancer-recommendation/</id> <content type="text/html" src="https://cwangg897.github.io/posts/redis-sorted-set-freelancer-recommendation/" /> <author> <name>Choi Wang Gyu</name> </author> <category term="Performance" /> <summary>개요 제가 다니는 회사는 프리랜서와 고객을 매칭해 주는 서비스입니다. 고객이 업무를 요청하면 해당 업무에 적합한 프리랜서를 찾아 매칭해 주는 방식으로 서비스가 동작합니다. 저희 서비스는 특정 시간대(11:00~13:00, 15:00~17:00)에 트래픽이 집중되는 피크 타임형 서비스입니다. 이 시간대에는 전체 시스템 트래픽이 약 100 TPS 까지 증가하며, 핵심 기능인 프리랜서 추천 로직에도 많은 요청이 몰립니다. 기존 추천 로직은 DB 기반으로 동작하고 있었는데, 트래픽이 증가하면서 DB 조회 부하와 응답 지연 문제가 발생했습니다. 이를 해결하기 위해 Redis Sorted Set과 사전 계산 전략을 도입한 과정을 정리했습니다. 문제 상황: 피크 타임에 집중되는 추천 조회 전체 트래픽...</summary> </entry> </feed>
