Skip to content

[HSC-423] user-log publish/admin 전달 비동기 분리 및 executor 계측 분리#277

Merged
tkv00 merged 1 commit into
mainfrom
perf/HSC-423
Mar 31, 2026
Merged

[HSC-423] user-log publish/admin 전달 비동기 분리 및 executor 계측 분리#277
tkv00 merged 1 commit into
mainfrom
perf/HSC-423

Conversation

@tkv00
Copy link
Copy Markdown
Contributor

@tkv00 tkv00 commented Mar 31, 2026

📝작업 내용

Burst 테스트에서 acceptedRate = 1임에도 실제 DB 반영 유실과 userLogTaskExecutor 포화가 반복적으로 관찰됐다.

이번 변경은 request path에서 Kafka publish와 admin internal 전달이 같은 executor를 공유하던 구조를 분리하고, 각 executor를 Grafana에서 따로 관측할 수 있도록 만드는 작업이다.

변경 요약

구분 변경 내용 목적
비동기 구조 admin log-feature 전달을 별도 async service로 분리 느린 admin HTTP 호출이 user-log publish 처리량을 직접 깎지 않도록 분리
executor adminLogFeatureTaskExecutor 신규 추가 publish 경로와 admin 전달 경로의 thread pool 분리
모니터링 admin-log-feature executor metric 추가 executor 포화 지점을 publish/admin 경로별로 분리 관측
customer 흐름 UserLogService에서 직접 HTTP 호출하던 구조를 dispatch service 위임으로 변경 self-invocation 없이 별도 executor 적용

대상 파일

파일 변경 내용
src/main/java/site/holliverse/customer/application/usecase/log/AdminLogFeatureDispatchService.java admin 전달 전용 async service 추가
src/main/java/site/holliverse/customer/application/usecase/log/UserLogService.java admin 전달 책임을 별도 dispatch service로 위임
src/main/java/site/holliverse/shared/config/runtime/CustomerRuntimeInfraConfiguration.java adminLogFeatureTaskExecutor bean 추가
src/main/java/site/holliverse/shared/monitoring/CustomerMonitoringBinder.java executor="admin-log-feature" metric 바인딩 추가

변경 전/후 구조

flowchart LR
    A["UserLogService"] --> B["userLogTaskExecutor"]
    B --> C["Kafka publish"]
    B --> D["Admin internal HTTP"]

    style B fill:#fbeeee,stroke:#c76262
Loading
flowchart LR
    A["UserLogService"] --> B["userLogTaskExecutor"]
    A --> E["AdminLogFeatureDispatchService"]

    B --> C["Kafka publish"]
    E --> F["adminLogFeatureTaskExecutor"]
    F --> D["Admin internal HTTP"]

    style B fill:#eef8ef,stroke:#5a9c67
    style F fill:#eef4ff,stroke:#5b80b7

Loading

🎫 Jira Ticket

  • Jira Ticket: HSC-423

#️⃣관련 이슈


@tkv00 tkv00 added 🗂️ area: BE 백엔드 영역 🔥 priority: P0 즉시 처리 필요(서비스/데모 블로커) ⚡ perf 성능 개선(쿼리/캐시/병목 제거 등) 🏷️ release 릴리즈 준비/버전 태깅/릴리즈 노트/릴리즈 브랜치 작업 release:patch 버전 patch bump: X.Y.(Z+1) deploy:api-server 배포 대상: customer-api Customer Team labels Mar 31, 2026
@github-actions github-actions Bot added Admin Team ⚠️ priority: P1 빠른 처리 필요(주요 기능 영향) labels Mar 31, 2026
@github-actions github-actions Bot changed the title user-log publish/admin 전달 비동기 분리 및 executor 계측 분리 [HSC-423] user-log publish/admin 전달 비동기 분리 및 executor 계측 분리 Mar 31, 2026
@tkv00 tkv00 merged commit e61a3e8 into main Mar 31, 2026
11 checks passed
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

이번 PR은 Admin 로그 전송을 비동기적으로 처리하기 위해 전용 실행자(adminLogFeatureTaskExecutor)와 AdminLogFeatureDispatchService를 도입했습니다. 리뷰에서는 해당 서비스가 인프라 레이어 등록 규칙(Rule 56)을 위반하여 @service 대신 @bean으로 등록되어야 함을 지적했으며, 시스템 안정성과 스레드 격리를 위해 실행자의 거부 정책을 CallerRunsPolicy에서 DiscardPolicy로 변경할 것을 제안했습니다.

/**
* admin log-feature 별도 executor로 분리
*/
@Service
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

🛡️ [위반 규칙]: Infrastructure Layer Registration (Rule 56)

AdminLogFeatureDispatchService는 외부 시스템(AdminLogFeaturesClient)과의 통신을 처리하는 기술적 어댑터 역할을 수행합니다. 저장소 스타일 가이드 규칙 56번에 따라 어댑터 성격의 컴포넌트에는 @Service를 사용하지 않아야 하며, @Configuration 클래스에서 @Bean으로 등록해야 합니다. 또한, 아키텍처 경계를 명확히 하기 위해 해당 클래스를 infrastructure 패키지로 이동하는 것을 권장합니다.

References
  1. 어댑터에 @component(@service 포함)를 사용하지 않고 @configuration + @bean을 사용해야 함 (link)

executor.setMaxPoolSize(16);
executor.setQueueCapacity(512);
executor.setThreadNamePrefix("admin-log-feature-");
executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

🛡️ [개선 제안]: Executor Isolation & Reliability

adminLogFeatureTaskExecutorCallerRunsPolicy를 적용하면, Admin API 호출 지연 시 호출자 스레드(userLogTaskExecutor)가 직접 작업을 수행하게 되어 격리 효과가 사라집니다. Admin 로그 전송이 비즈니스 핵심 흐름에 지장을 주지 않아야 한다면, 시스템 전체의 안정성을 위해 DiscardPolicy를 적용하여 업스트림 스레드 풀을 보호하는 것이 좋습니다.

Suggested change
executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.DiscardPolicy());

@github-actions
Copy link
Copy Markdown

🧪 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-03-31 23:15 UTC

Scope Line Branch Line Graph Branch Graph Verdict
Overall 40.5% 29.4% ████████░░░░░░░░░░░░ ██████░░░░░░░░░░░░░░ ⚠️⚠️
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.shared.monitoring 0.0% N/A 77 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
2 site.holliverse.customer.application.usecase.log 0.0% 0.0% 70 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
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.fastapi 0.0% 0.0% 28 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
6 site.holliverse.customer.integration.external 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.UserLogService 0.0% 0.0% 51 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
2 site.holliverse.shared.monitoring.CustomerMetrics 0.0% N/A 50 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
3 site.holliverse.infra.kafka.consumer.RecommendationKafkaConsumer 0.0% 0.0% 44 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
4 site.holliverse.customer.application.usecase.recommendation.RecommendationKafkaConsumeUseCase 0.0% 0.0% 42 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
5 site.holliverse.admin.application.usecase.CalculateLogChurnScoreService 0.0% 0.0% 38 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
6 site.holliverse.admin.application.usecase.CalculateChurnScoreService 0.0% 0.0% 37 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
7 site.holliverse.customer.coupon.application.UseMemberCouponUseCase 0.0% 0.0% 34 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
8 site.holliverse.admin.application.usecase.ChurnRiskReason$ReasonCode 0.0% 0.0% 31 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
9 site.holliverse.customer.integration.fastapi.FastApiRecommendationClient 0.0% 0.0% 28 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
10 site.holliverse.customer.integration.external.AdminLogFeaturesClient 0.0% 0.0% 28 ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
🧩 Changed files coverage breakdown (4 files)
File Line Branch Lines Verdict Line Graph Branch Graph
src/main/java/site/holliverse/customer/application/usecase/log/AdminLogFeatureDispatchService.java 0.0% N/A 2 ⚠️ ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
src/main/java/site/holliverse/customer/application/usecase/log/UserLogService.java 0.0% 0.0% 51 ⚠️⚠️ ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
src/main/java/site/holliverse/shared/monitoring/CustomerMonitoringBinder.java 0.0% N/A 27 ⚠️ ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░
src/main/java/site/holliverse/shared/config/runtime/CustomerRuntimeInfraConfiguration.java N/A N/A 0 ✅✅ ░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Admin Team 🗂️ area: BE 백엔드 영역 Customer Team deploy:api-server 배포 대상: customer-api ⚡ perf 성능 개선(쿼리/캐시/병목 제거 등) 🔥 priority: P0 즉시 처리 필요(서비스/데모 블로커) ⚠️ priority: P1 빠른 처리 필요(주요 기능 영향) release:patch 버전 patch bump: X.Y.(Z+1) 🏷️ release 릴리즈 준비/버전 태깅/릴리즈 노트/릴리즈 브랜치 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant