Direct API call vs through a queue

judgment
상황

주문이 완료되면 알림 서비스를 호출해서 푸시/이메일을 보내야 합니다. 알림 API를 바로 부를지, 중간에 큐를 둘지 정해야 하는 상황이에요.

😴 Boring — Direct synchronous API call (그냥 바로 호출)

언제: 응답을 받아야 다음 단계로 갈 수 있을 때(결제 승인처럼), 트래픽이 예측 가능하고 받는 쪽이 충분히 따라올 때. 실패하면 사용자에게 바로 에러를 보여줘도 되는 경우.

비용: 받는 서비스가 느려지거나 죽으면 내 서비스도 같이 느려지거나 실패함. 트래픽 스파이크가 그대로 전달돼서 받는 쪽을 무너뜨릴 수 있고, 재시도 로직이 호출하는 쪽마다 복붙되기 시작함.

✨ Novel — Message queue in between (SQS/Kafka 같은 큐를 중간에)

언제: 받는 쪽이 잠깐 죽어도 작업이 사라지면 안 될 때(알림, 정산, 이메일), 트래픽 스파이크를 흡수해야 할 때, 호출하는 쪽이 응답을 기다릴 필요가 없을 때.

비용: 운영할 인프라가 하나 늘고, 재시도 때문에 같은 메시지가 두 번 올 수 있어서 컨슈머에 멱등성 처리가 필수. '이거 지금 처리됐어?'를 추적하기 어려워지고, DLQ 모니터링·큐 깊이 알람까지 챙길 게 늘어남.

⚖️ 기본 판단

기본은 직접 호출입니다. 코드가 단순하고 실패가 그 자리에서 바로 보이니까요. 다만 응답을 기다릴 필요가 없는 작업인데 다운스트림 장애 때마다 일이 실제로 유실되거나, 스파이크 때 받는 쪽이 못 버티는 신호가 보이면 그때 큐를 넣습니다.

🚨 트립와이어 — 이 신호가 오면 바꾼다
  • 다운스트림 호출 때문에 내 API p99가 500ms를 넘기 시작함
  • 받는 서비스 배포·장애 때마다 우리 쪽 5xx가 1% 이상 같이 튀고, 그때 날아간 알림을 수동으로 복구하고 있음
  • 스파이크 때 받는 쪽이 429/타임아웃을 뱉어서 작업이 실제로 유실됨(예: 알림 누락 CS 발생)
  • 재시도+백오프 코드가 호출하는 서비스 3곳 이상에 복붙돼 있음

🔧AWS SQSKafkaRedis Streamsresilience4j (retry/backoff/circuit breaker)DLQ + queue-depth alarm (CloudWatch)

🗣 영어 한 줄 평결

I default to a direct call; I only add a queue once retries pile up or spikes start dropping work.

checking microphone…

⚔️ Defend it — AI 시니어가 반박한다. 영어로 버텨라.

첫 메시지로 네 입장을 영어로 선언해라 — 예: “I'd start with Direct synchronous API call here, and only switch when …” 그러면 상대가 반박을 시작한다. 근거·숫자·트립와이어로 받아쳐라.

두어 번은 치고받은 뒤에 채점