전체 글 114

[SPRING] 스프링 로그 모니터링 전 로그 설계

모든 요청 흐름을 추적하고, 유저 인증 정보를 로그에 구조화하여 담는 방법에 대해 정리특히 인증 기반 API를 운영하면서 실시간 대응과 문제 분석을 위해 로그 체계를 정리 1️⃣ 전체 로그 흐름 설계 목표 traceId 기반으로 요청 → 응답 → 예외 흐름 추적인증 정보 기반의 핵심 userId, userEmail 로그에 포함인증 실패나 예외 발생 시에도 동일한 맥락 유지/admin/** 엔드포인트에 대해서는 별도 AOP 로그 확보 2️⃣ 필터 기반 MDC 구조화 처리 Spring의 OncePerRequestFilter를 활용하여 요청 시점에 traceId, IP, 인증 정보 등을 MDC에 세팅하고,응답 및 예외 시에도 해당 정보를 그대로 사용@Overrideprotected void doFilte..

SPRING 2025.06.19

[250602 트러블 슈팅]Playwright 병렬 크롤링 중 TargetClosedError 해결기

1️⃣ 문제 상황Spring Boot 기반 크롤러 프로젝트에서 Playwright(Java) 를 이용해 Danawa 상품 리뷰를 병렬로 크롤링하던 중, 다음과 같은 에러가 반복적으로 발생했습니다:TargetClosedError: Target page, context or browser has been closedPlaywrightException: Cannot find object to call __adopt__: browser-context@xxxxxxx병렬 처리: Virtual Thread 기반프록시: socks5://127.0.0.1:1080 (로컬 프록시 서버)각 Catalog 마다 browser.newContext() 호출2️⃣ 원인 분석Playwright는 Java ↔ JS 런타임 간 통신을 ..

SPRING 2025.06.03

[250602 트러블 슈팅] 크롤링 도중에 IP밴

1️⃣ EC2 인스턴스 설정문제 상황 : 가상 쓰레드를 사용한 병렬 크롤링으로 인한 IP 밴목표 :다나와에서 2560개의 상품 리뷰를 크롤링하기처음에는 속도를 위해 단순하게 병렬 처리로 여러 스레드가 동시에 요청을 보내도록 구현public class DanawaStarCommentCrawler implements CommandLineRunner { private static final int BATCH_SIZE = 10; private final ReviewRepository reviewRepository; private final CatalogRepository catalogRepository; private final ExecutorService executor = Executors.newVirtua..

SPRING 2025.06.02

[SPRING] Lettuce 분산 락 트러블슈팅

1️⃣ 문제 상황동일 좌석에 대해 100명 이상이 동시에 예매 시도할 때 정상적으로는 단 1명만 예매에 성공해야 하지만2~3명이 동시에 예매 성공하는 현상이 발생!📌 테스트 시나리오대상 좌석: A-1동시 요청 수: 200건결과: 예매 성공 수 2~3건 → Race Condition 2️⃣ 문제 상황100건 이하의 동시 요청에서는 문제 없이 정확히 1건만 예매에 성공하고, 나머지는 실패 처리그러나 동시 요청이 100건을 초과하면, 2~3건의 예매가 동시에 성공하는 현상이 발생즉, 동일 좌석에 대한 중복 예매가 발생하는 Race Condition 상황이 발생한 것 3️⃣ 원인 분석분산 락 자체는 정상적으로 동작그럼에도 중복 성공이 발생한 이유는 락 획득과 트랜잭션 시작 사이의 시간 차이 때[BookingS..

SPRING 2025.05.28

[SPRING] Lettuce 분산 락 구현

1️⃣ Redis + Lettuce 분산 락 구현 방식 요약Lettuce를 활용한 SETNX 기반의 분산 락 구조간단하면서도 안정적인 구조로, Redis를 통해 멀티 인스턴스 환경에서도 예매 중복을 제어 가능✅ 락 키 구성lock:seat:{seatId} 형식 (예: lock:seat:1001)좌석 단위로 분산 락을 설정합니다.✅ 락 소유자 식별락 값을 UUID로 설정하여, 락 소유자를 명확히 구분합니다.락 해제 시 자신이 소유한 락만 해제되도록 보장합니다.✅ 락 만료시간기본 5초(px=5000)로 설정하여 데드락을 방지합니다.✅ 전체 구조[BookingController] ↓[BookingFacade] ← 분산 락 시도 ↓[LettuceDistributedLockService]..

SPRING 2025.05.27

[SPRING] 동시성 제어 분산 락

1️⃣ 동시성 제어를 하는 이유공연 예매 서비스에서는 수많은 사용자가 동시에 동일한 좌석을 클릭할 수 있다.예를 들면, A-1 좌석에 대해 100명의 사용자가 거의 동시에 예매 버튼을 누른다면, 단 1명만 예매에 성공해야 한다.하지만 별도의 동시성 제어 없이 구현된 서비스라면, 이 좌석이 동시에 여러 명에게 중복 예약되는 치명적인 문제가 발생할 수 있다. 이를 해결하기 위한 핵심 기술이 바로 분산 락(Distributed Lock) 2️⃣ 분산 락(Distributed Lock)이란?분산 락이란, 다중 인스턴스 환경에서 동시에 같은 자원에 접근하는 것을 제어하기 위한 메커니즘여러 서버 혹은 스레드가 동시에 같은 좌석을 예약하려는 상황에서 단 하나만 성공하도록 보장하는 방식 DB Lock, Redis 차..

SPRING 2025.05.26

[SPRING] 커스텀 메트릭 수집 및 시각화

1️⃣ 환경 구성의존성 추가(Gradle)dependencies { implementation 'io.micrometer:micrometer-registry-prometheus' implementation 'org.springframework.boot:spring-boot-starter-actuator'} application.yml 설정management: endpoints: web: exposure: include: "prometheus" metrics: export: prometheus: enabled: true 2️⃣ 커스텀 메트릭 코드 작성Counter, Timer, Gauge 등을 Micrometer에서 제공 회원가입 수 카운..

SPRING 2025.05.20

[SPRING] 메트릭 기반 모니터링 시스템(Prometheus, Grafana)

1️⃣ 메트릭(Metric)이란?정량적 수치 기반의 데이터예: CPU 사용률, HTTP 요청 수, 응답 지연 시간, 쓰레드 수 등로그가 텍스트 위주의 이벤트 기록이라면, 메트릭은 수치 기반의 시간 시계열 데이터 2️⃣ 모니터링 시스템 구성도 Spring Boot : Micrometer → /actuator/prometheus 로 메트릭 노출Prometheus : 주기적으로 애플리케이션에서 메트릭 수집 (pull 방식)Grafana : Prometheus 데이터를 시각화하고 대시보드로 제공 3️⃣ 각 요소의 역할Spring Boot + Micrometer + ActuatorMicrometer: 다양한 모니터링 시스템에 메트릭을 전달할 수 있는 추상화 계층Actuator: /actuator/prometheu..

SPRING 2025.05.19

[250516 TIL] 실전 팀 프로젝트 시작

1️⃣ 프로젝트프로젝트명 : 티켓구조대(Ticket911) 우리가 목표하는 도전기능 - 동시성 제어, CI/CDLCK 티켓팅대기열 리스트 등2️⃣ 담당업무인증/인가 - 이승현티켓 - 김태익좌석, 공연장 - 박기범공연 - 정석현동시성CI/CD3️⃣ 와이어프레임https://www.notion.so/teamsparta/1f52dc3ef514807a8678c57c1d5d7c00 와이어 프레임 | Notion메인 페이지www.notion.so4️⃣ API 명세서(내것만)5️⃣ ERD DIAGRAM6️⃣ 컨밴션 🎯 커밋 컨벤션기본 적인 커밋 메시지 구조는 제목,본문,꼬리말 세가지 파트로 나누고, 각 파트는 빈줄을 두어 구분더보기type: subject body footer ex) git commit -m "Fi..

TIL 2025.05.16

[SPRING] 조건 검색 개선 3탄 (분리 조회,Projection, 복합 인덱스)

📝 실험 배경이전 포스트에서 QueryDSL 후 서비스에서 처리 방식으로 많은 성능 개선을 느꼈다.Todo 리스트만 먼저 조회` 를 할 때 `TodoPartitioned` 를 한번에 가져오는게 아니라 `ID(PK)` 필드만 Projection 해서 조회한다면 커버링 인덱스에 의해서 더 빠르게 동작할 것 같은데 여기까지 실험을 연장해볼 수 있을까요? 이번엔 해당 피드백을 받아 개선을 진행했다.https://sukh115.tistory.com/100 [SPRING] 조건 검색 개선 (인덱싱, 파티셔닝, 분리 조회)📝 실험 배경아래 포스트에서 최적 복합 인덱스로 성능 개선을 느낀적이 있었다. 이번에는 그걸 넘어서 파티셔닝으로 성능 개선을 느끼는게 목적이다.https://sukh115.tistory.com/..

SPRING 2025.05.15