3.5 KiB
3.5 KiB
title, category, error_codes, severity, owner, last_updated, status
| title | category | error_codes | severity | owner | last_updated | status | |
|---|---|---|---|---|---|---|---|
| Runbook — async executor rejected | TRANSIENT_DEPENDENCY |
|
P1 | oncall | 2026-06-13 | stub |
Runbook: async executor rejected (runbook://job/executor-rejected)
1. Trigger
이 runbook은 다음 alert에서 발동됩니다.
- alert name:
executor_rejected - alert payload 필수 field:
error.code=JOB_EXECUTOR_REJECTED,executor_name,policy,runbook_link - 임계:
executor.rejected.total> 0 for 1m (p1) — bounded pool이 saturation으로 task를 거부 - 보조 신호:
executor.saturationgauge > queue capacity의 80% for 5m (p2)
2. First Response (5분 이내)
Step 1 — 확인
- ERROR log에서
JOB_EXECUTOR_REJECTED라인 확인:executor_name,policy=AbortPolicy,queue_size추출 executor.saturation패널에서 큐 점유율 추이 확인 — 일시적 burst인지 지속 saturation인지 판별- 동시 유입 원인 파악: 신규 배포 / 트래픽 spike / 다운스트림 지연으로 worker가 장기 점유되는지
Step 2 — 임시 격리
- AbortPolicy 거부는 호출부에
RejectedExecutionException으로 surface됨 — fire-and-forget@Async호출이면 호출부의 async-exception 처리(log/metric)로 흡수됐는지 확인 - 지속 saturation이면 유입 측(트래픽/스케줄러 빈도)을 우선 감속
3. Diagnosis
- log query:
{service="app"} | error.code="JOB_EXECUTOR_REJECTED" | stats count by executor_name - metric panel:
executor.saturation{executor_name},executor.rejected.total{executor_name, policy} - 가능한 원인 우선순위:
- 다운스트림 의존성 지연 → worker가 반납되지 않아 큐 포화 (가장 흔함)
- 트래픽 spike → 정상 부하 한계 초과
- pool 과소 설정 (
APP_ASYNC_EXECUTOR_*) - non-idempotent 작업이 retry로 누적
4. Mitigation
- 단기: 유입 감속(상위 rate-limit / 스케줄러 interval 확대) 또는 다운스트림 의존성 회복
- pool 재조정(restart-only):
APP_ASYNC_EXECUTOR_CORE_SIZE/APP_ASYNC_EXECUTOR_MAX_SIZE/APP_ASYNC_EXECUTOR_QUEUE_CAPACITY— ⚠ queue를 무한정 키우지 말 것(unbounded 금지, D7). 부하테스트로 수치 검증 후 변경 - CallerRunsPolicy로의 전환은 use-case 차원의 명시적 결정 필요(request thread latency 침식 — TPE-JDK21-C6)
5. Escalation
- 다운스트림 의존성 장애가 근본 원인이면 해당 의존성 오너에게 escalate
- pool 재조정으로도 saturation이 지속되면 용량 계획(capacity planning) 오너에게 page
6. Recovery / Verification
- 회복 확인:
executor.rejected.total증가 멈춤,executor.saturation< 80% 정상화 - 거부된 작업의 재처리 경로(멱등 retry / 다음 스케줄 cycle) 정상 동작 확인
7. Related
- error-codes.yaml rows:
JOB_EXECUTOR_REJECTED(TRANSIENT_DEPENDENCY, 503, retryable=true, retry_after 5s) - metrics.yaml:
executor.rejected.total{executor_name, policy},executor.saturation{executor_name} - 코드:
app-bootstrapasync/AsyncExecutorConfig(bounded executor),async/LoggingAbortPolicy(reject log+metric),async/BackgroundJobMetrics - env:
APP_ASYNC_EXECUTOR_CORE_SIZE/APP_ASYNC_EXECUTOR_MAX_SIZE/APP_ASYNC_EXECUTOR_QUEUE_CAPACITY - 관련 runbook: job-timeout, job-dead-letter
- 관련 branch: feature-background-job-async-contract (D7 saturation policy)
Stub 상태 안내: 이 runbook은 skeleton 단계의 stub. 실제 부하 프로파일·alert 채널·pool 수치 확정 시 보강 필요.