Skip to content

[HSC-424] user-log admin dispatch 아웃박스 적재 경량화 및 재시도 완화#281

Merged
tkv00 merged 2 commits into
mainfrom
perf/HSC-424
Apr 1, 2026
Merged

[HSC-424] user-log admin dispatch 아웃박스 적재 경량화 및 재시도 완화#281
tkv00 merged 2 commits into
mainfrom
perf/HSC-424

Conversation

@tkv00
Copy link
Copy Markdown
Contributor

@tkv00 tkv00 commented Apr 1, 2026

📝작업 내용

outbox 도입 이후 Burst 구간에서 customer ingress가 먼저 503을 반환하던 문제에 대한 hot path 경량화와 retry scheduler 완화.

문제 상황

항목
acceptedRate 0.1457
failedRate 0.8542
http p95 9267.1732ms
sentEvents 18,915

기존 outbox 구현에서는 request path에서 admin 대상 이벤트를 한 건씩 저장했고, retry scheduler도 짧은 주기와 큰 batch로 DB를 동시에 두드리고 있었다. 그 결과 Burst 구간에서 /api/v1/customer/user-logs ingress 자체가 503을 반환하기 시작했다.

해결 과정

단계 내용 의도
배치 적재 publishBatch()에서 outbox 적재를 일괄 처리로 전환 request path DB write 횟수 축소
flush 제거 단건 저장을 saveAndFlush() 대신 save()로 유지 즉시 flush 비용 제거
fallback 유지 batch 저장 실패 시 개별 저장 fallback duplicate/store error 처리 유지
scheduler 완화 initial delay, fixed delay, batch size, retry delay 조정 retry path와 request path DB 경합 완화

변경 요약

구분 내용 목적
outbox 적재 batch enqueue 추가 hot path 경량화
user-log 경로 publishBatch() 일괄 적재 전환 이벤트별 반복 저장 제거
scheduler 설정 주기/배치/재시도 간격 완화 burst 중 DB 압박 완화

구조도

flowchart LR
    A["publishBatch()"] --> B["Kafka publish 반복"]
    A --> C["Outbox batch enqueue"]
    D["Scheduler"] --> E["소량 batch claim"]
    E --> F["dispatch retry"]

    style C fill:#eef8ef,stroke:#5a9c67
    style D fill:#eef4ff,stroke:#5b80b7
Loading

👀변경 사항

구현 항목

항목 파일 내용
batch 적재 src/main/java/site/holliverse/customer/application/usecase/log/UserLogAdminDispatchOutboxService.java enqueueBatch() 추가, saveAll() 기반 적재
batch 연동 src/main/java/site/holliverse/customer/application/usecase/log/UserLogService.java publishBatch()에서 일괄 outbox 적재 사용
scheduler 완화 src/main/java/site/holliverse/customer/application/usecase/log/UserLogAdminDispatchScheduler.java initial delay / fixed delay 조정
설정 조정 src/main/resources/application-customer.yml batch size, retry delay, scheduler 기본값 조정

변경 전/후

Before After
batch 요청마다 admin 대상 이벤트를 개별 outbox 저장 batch 요청 단위 일괄 outbox 저장
scheduler가 1초 주기, 100건 단위로 재전달 scheduler가 5초 후 시작, 3초 주기, 20건 단위 재전달
request path와 retry path가 동시에 DB를 강하게 압박 request path write 수와 retry 경합 강도 완화

커밋 단위

커밋 내용
[HSC-424] perf: 사용자 로그 아웃박스 배치 적재 적용 batch enqueue 추가, publishBatch() 연동
[HSC-424] perf: 사용자 로그 dispatch 재시도 기본값 완화 scheduler 주기, batch size, retry delay 완화

확인 메모

항목 내용
이전 현상 k6 console에서 503 다수 발생
기대 효과 ingress 503 감소, acceptedRate 회복, scheduler와 request path 경합 완화
후속 확인 동일 Burst 재실행 후 acceptedRate / failedRate / p95 / DB total_events 비교

🎫 Jira Ticket

  • Jira Ticket: HSC-424

#️⃣관련 이슈


@tkv00 tkv00 added 🗂️ area: BE 백엔드 영역 🚑 hotfix 프로덕션 긴급 수정(우회/긴급 패치 포함) 🔥 priority: P0 즉시 처리 필요(서비스/데모 블로커) 🏷️ release 릴리즈 준비/버전 태깅/릴리즈 노트/릴리즈 브랜치 작업 release:patch 버전 patch bump: X.Y.(Z+1) deploy:api-server 배포 대상: customer-api labels Apr 1, 2026
@github-actions github-actions Bot added Customer Team release:minor 버전 minor bump: X.Y.0 ⚡ perf 성능 개선(쿼리/캐시/병목 제거 등) labels Apr 1, 2026
@github-actions github-actions Bot changed the title user-log admin dispatch 아웃박스 적재 경량화 및 재시도 완화 [HSC-424] user-log admin dispatch 아웃박스 적재 경량화 및 재시도 완화 Apr 1, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이 풀 리퀘스트는 사용자 로그 아웃박스 처리를 위한 배치 저장 기능을 도입하고 관련 스케줄러 설정을 최적화합니다. 코드 리뷰 결과, enqueueBatch 메서드에서 saveAll 호출 중 예외 발생 시 트랜잭션이 롤백 전용으로 마킹되어 catch 블록 내의 개별 저장 시도가 실패할 수 있는 심각한 로직 오류가 확인되었습니다. 또한, isAdminTarget 판별 로직과 decodeTsidToLong 유틸리티 메서드가 여러 클래스에 중복 정의되어 있으므로, 이를 shared 모듈로 이동하여 프로젝트 아키텍처 가이드를 준수하고 유지보수성을 높여야 합니다.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 1, 2026

🧪 Test Coverage Report (JaCoCo)

overall__line overall__branch changed__line changed__branch

기준(soft, workflow는 실패 안 함): Overall line 70% / branch 50%, Changed line 80% / branch 60% · Generated: 2026-04-01 03:52 UTC

Scope Line Branch Line Graph Branch Graph Verdict
Overall 38.2% 28.0% ████████░░░░░░░░░░░░ ██████░░░░░░░░░░░░░░ ⚠️⚠️
Changed 0.0% 0.0% ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░ ⚠️⚠️

Package line spark (sample): ▃▂▁▂▂▄▄·▇█▁▆▆▆·▆▁▁▆█▇▃▁▁▁██▁▁▃
Package branch spark (sample): ▃▁·▁▁·▁·▇··▅▆▅·▅▁▁▅▇▇▂▁·▁·█▁▁▁

📦 Package coverage (worst 10)

Rank Package Line Branch Lines Line Graph Branch Graph
1 site.holliverse.customer.application.usecase.log 0.0% 0.0% 184 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
2 site.holliverse.shared.monitoring 0.0% N/A 89 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
3 site.holliverse.customer.coupon.application 0.0% 0.0% 61 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
4 site.holliverse.infra.kafka.consumer 0.0% 0.0% 44 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
5 site.holliverse.customer.integration.external 0.0% 0.0% 30 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
6 site.holliverse.customer.integration.fastapi 0.0% 0.0% 28 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
7 site.holliverse.customer.application.usecase.counsel 0.0% 0.0% 14 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
8 site.holliverse.customer.coupon.web 0.0% 0.0% 12 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
9 site.holliverse.shared.config.runtime 0.0% N/A 11 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
10 site.holliverse.customer.web.util 0.0% 0.0% 8 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░

🧨 Lowest coverage classes (worst 10)

Rank Class Line Branch Lines Line Graph Branch Graph
1 site.holliverse.customer.application.usecase.log.UserLogAdminDispatchOutboxService 0.0% 0.0% 71 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
2 site.holliverse.shared.monitoring.CustomerMetrics 0.0% N/A 62 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
3 site.holliverse.customer.application.usecase.log.UserLogService 0.0% 0.0% 55 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
4 site.holliverse.infra.kafka.consumer.RecommendationKafkaConsumer 0.0% 0.0% 44 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
5 site.holliverse.customer.application.usecase.recommendation.RecommendationKafkaConsumeUseCase 0.0% 0.0% 42 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
6 site.holliverse.admin.application.usecase.CalculateLogChurnScoreService 0.0% 0.0% 38 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
7 site.holliverse.admin.application.usecase.CalculateChurnScoreService 0.0% 0.0% 37 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
8 site.holliverse.customer.coupon.application.UseMemberCouponUseCase 0.0% 0.0% 34 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
9 site.holliverse.admin.application.usecase.ChurnRiskReason$ReasonCode 0.0% 0.0% 31 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
10 site.holliverse.customer.integration.external.AdminLogFeaturesClient 0.0% 0.0% 30 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
🧩 Changed files coverage breakdown (3 files)
File Line Branch Lines Verdict Line Graph Branch Graph
src/main/java/site/holliverse/customer/application/usecase/log/UserLogAdminDispatchOutboxService.java 0.0% 0.0% 71 ⚠️⚠️ ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
src/main/java/site/holliverse/customer/application/usecase/log/UserLogAdminDispatchScheduler.java 0.0% N/A 2 ⚠️ ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
src/main/java/site/holliverse/customer/application/usecase/log/UserLogService.java 0.0% 0.0% 55 ⚠️⚠️ ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░

🔎 HTML 리포트: Actions → Artifacts → jacoco-html · XML: jacoco-xml

@tkv00 tkv00 merged commit 3ed1845 into main Apr 1, 2026
12 checks passed
@tkv00 tkv00 removed the release:minor 버전 minor bump: X.Y.0 label Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🗂️ area: BE 백엔드 영역 Customer Team deploy:api-server 배포 대상: customer-api 🚑 hotfix 프로덕션 긴급 수정(우회/긴급 패치 포함) ⚡ perf 성능 개선(쿼리/캐시/병목 제거 등) 🔥 priority: P0 즉시 처리 필요(서비스/데모 블로커) release:patch 버전 patch bump: X.Y.(Z+1) 🏷️ release 릴리즈 준비/버전 태깅/릴리즈 노트/릴리즈 브랜치 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant