-
Notifications
You must be signed in to change notification settings - Fork 1
ADR 0002 Portal Job Outbox and SQS
SANGMIN PARK edited this page Jul 17, 2026
·
1 revision
- 상태: Accepted
- 결정일: 2026-03-14
- 마지막 검증: 2026-07-18
수원대학교 포털 로그인과 학사 데이터 수집은 외부 시스템의 응답 시간과 장애에 영향을 받습니다. API 요청 스레드에서 스크래핑 전체를 수행하면 timeout과 중복 요청에 취약합니다.
DB에 작업만 저장한 뒤 SQS 발행이 실패하거나, SQS에만 발행한 뒤 DB 저장이 실패하면 작업 상태와 실제 메시지가 어긋날 수 있습니다. 포털 자격 증명을 포함한 같은 요청이 재시도될 때 중복 Worker 실행도 막아야 합니다.
- 포털 연동 요청은 장기 작업으로 취급하고
202 Accepted와jobId를 반환합니다. -
scrape_jobs와scrape_job_outbox를 같은 DB 트랜잭션에 저장합니다. - 사용자와
Idempotency-Key로 기존 Job을 찾고 요청 fingerprint가 다르면 충돌로 거부합니다. - DB 커밋 후 해당 Outbox를 SQS에 동기 발행하고, Outbox가
SENT, Job이RUNNING인지 확인한 뒤 요청을 성공으로 반환합니다. - Worker는 SQS 메시지를 소비해 포털 작업을 수행하고 Backend는 Job 조회 API로 상태를 제공합니다.
- Outbox는
PENDING,RETRYABLE_FAILED,SENT,DEAD상태와 시도 횟수, 다음 시도 시각, 마지막 오류를 저장합니다.
구현은 단순하지만 외부 포털의 지연이 API timeout과 Lambda 실행 시간으로 전파됩니다. 클라이언트 재시도도 실제 작업 중복으로 이어질 수 있습니다.
DB와 Queue 사이의 원자성을 보장할 수 없고, 메시지 발행 후 API가 실패하면 클라이언트와 서버가 작업 존재 여부를 다르게 인식합니다.
API 응답은 빨라지지만 현재 운영 경로에는 dispatchEligibleOutboxes()를 주기적으로 호출하는 코드가 없습니다. 자동 릴레이가 없는 상태에서 Job이 QUEUED에 고립될 수 있어 채택하지 않았습니다.
- Job과 발행할 메시지가 하나의 DB 트랜잭션으로 보존됩니다.
- 같은 Idempotency Key와 같은 요청은 기존 Job을 재사용합니다.
-
202응답 시점에 SQS 발행 성공을 확인하므로 즉시 발행 실패를 호출자에게 알릴 수 있습니다. -
jobId,outboxId, Queue Message ID로 API부터 Worker까지 추적할 수 있습니다.
- 요청 응답 시간이 DB 저장뿐 아니라 SQS 발행 시간에도 영향을 받습니다.
- Outbox payload에 포털 자격 증명이 포함되므로 DB 접근, 로그, 운영 조회를 엄격히 제한해야 합니다.
-
RETRYABLE_FAILED상태는 저장되지만 현재 자동 배치 호출부가 없습니다. 자동 백그라운드 재처리를 전제로 운영하면 안 됩니다. - DB와 SQS를 함께 운영하고 상태 전이를 관리해야 하므로 단순 Queue 발행보다 구현이 복잡합니다.
- Outbox payload와 Job request payload를 로그, Issue, 일반 운영 SQL 결과에 포함하지 않습니다.
- 같은 Idempotency Key에 다른 요청을 보내면
C07 IDEMPOTENCY_KEY_CONFLICT로 처리합니다. -
QUEUED장애는 Job과 Outbox 상태를 함께 확인하고 DB 상태만 수동 변경하지 않습니다. - Worker 메시지 계약을 바꾸면 Backend 발행 DTO와 Worker 소비 코드를 함께 배포합니다.
- EventBridge Scheduler나 별도 Relay가
dispatchEligibleOutboxes()를 안정적으로 실행하게 됩니다. - 포털 자격 증명을 일회성 Token이나 별도 보안 저장소 참조로 대체합니다.
- SQS 발행 지연이 API 응답 목표를 지속해서 위반합니다.