워크로드별 async executor 분리 (AI 연동 / 이벤트 후속 처리) - #262
Conversation
📊 코드 커버리지 리포트
|
|
현재 PR에 다만 이 전제는 #261에서 순서는 다음 중 하나로 하면 될 것 같습니다.
즉 #262는 현재 상태 기준으로는 #261 이후 상태에 의존하고 있어 머지 순서를 명확히 하거나 diff를 분리하는 게 안전해 보입니다. |
정확한 지적 감사합니다. 말씀하신 대로입니다 — 이 브랜치는 #261(feature/#259) 위에서 분기해 작업했고, 관측 파일(AsyncTaskFinalFailure description·패널4의 task/action)도 #261에서 태그 키셋이 task·action으로 통일된 상태를 전제로 반영되어 있습니다. 그래서 #262 diff에 메트릭 등록부 변경 없이 관측 변경만 보이는 것이 맞습니다. 순서는 제안해주신 1번으로 진행하겠습니다. #261을 먼저 머지한 뒤, #262를 최신 main 기준으로 rebase해서 관측 파일 충돌을 정리하고 머지하겠습니다. #261 머지 전까지 이 PR은 머지하지 않겠습니다. |
느린 AI 호출(최대 60s)이 기본 executor 를 점유해 빠른 이벤트 처리(웹소켓 푸시)를 지연시키는 것을 격리. - aiTaskExecutor 신설: core3 / max8 / queue30, prefix ai-async- (AI 서버 처리량이 병목이므로 동시성을 낮게 잡고 큐로 흡수) - 이주: LinkSyncEventListener.handleLinkSyncEvent, RagChatService.generateAnswer → @async("aiTaskExecutor"). 빠른 작업(SummaryStatusEventListener)은 기본 유지 - CallerRunsPolicy·graceful shutdown 30s·MdcTaskDecorator 기본 executor 와 동일 - 기본 executor 는 opt-in 구조 유지: 이름 없는 @async 는 빠른 풀로 - 포화 관측 executor별 확장: 큐 포화 알림을 절대값 → 사용률 기반 (queued/(queued+remaining) >= 0.8)으로 일반화, 패널·룰 name 정규식 분리
daa1b1d to
a7599ab
Compare
관련 이슈
PR 설명
느린 AI 연동 작업과 빠른 이벤트 후속 처리가 단일 전역 executor 를 공유하던 구조를 분리했습니다. AI 전용 executor(
aiTaskExecutor)를 신설해 느린 작업을 격리하고, 포화 관측(대시보드·알림)을 executor별로 확장했습니다. (#256 PR 리뷰에서 도출)배경
@Async작업이 단일applicationTaskExecutor(core5/max20/queue100)를 공유했습니다.워크로드 인벤토리 (@async 전수 조사)
LinkSyncEventListener.handleLinkSyncEventRagChatService.generateAnswerSummaryStatusEventListener.handleSummaryStatusEventLinkEventListener(동기, @async 없음)와SummaryWorker(전용 스레드)는 executor 를 타지 않아 대상이 아닙니다.변경 사항
1.
aiTaskExecutor신설core 3 / max 8 / queue 30, prefixai-async-CallerRunsPolicy유지: link-sync 는 유실 불가 정합성 작업(백프레셔 필요), 채팅 답변은 caller-runs 로 동기 강등되어도 사용자가 어차피 응답을 기다리는 요청이라 수용 가능합니다.MdcTaskDecorator·graceful shutdown(30s) 동일 적용. awaitTermination 은 AI 호출(60s)보다 짧지만, 종료 시 잘린 작업은 기존@Recover/dead-letter 경로로 수습되는 구조이므로 배포 속도를 위해 30s 를 유지했습니다.2. 기본 executor 는 opt-in 구조로 유지
@Async는 계속applicationTaskExecutor(빠른 작업)로 갑니다. 느린 작업만@Async("aiTaskExecutor")로 명시 지정합니다.3. 포화 관측 executor별 확장
queued >= 80)에서 사용률 기반(queued / (queued + remaining) >= 0.8)으로 일반화 — executor별 큐 용량(100/30)이 달라도 룰 하나로 커버되고, executor 가 늘어도 정규식에 이름만 추가하면 됩니다.name라벨로 executor별 분리 표시.확인
./gradlew test전체 통과/actuator/prometheus에서executor_*{name="aiTaskExecutor"}지표 노출 확인ai-async-*인 것 확인, 웹소켓 푸시는async-*유지 확인참고