서드파티 API 안전 통합: 재시도, 타임아웃, 서킷 브레이커
장애 시에도 앱이 동작하도록 하는 안전한 서드파티 API 통합. 타임아웃, 재시도, 서킷 브레이커와 빠른 점검 방법을 배우세요.

서드파티 API가 핵심 워크플로를 막는 이유
서드파티 API는 명확한 "다운" 상태처럼 보이지 않는 방식으로 실패할 수 있습니다. 가장 흔한 문제는 느려지는 것입니다. 요청이 멈추고 응답이 늦게 도착하며 앱이 계속 기다립니다. 이러한 호출이 중요 경로에 놓이면 외부의 작은 문제도 내부 시스템에서 쌓입니다.
이렇게 해서 지역적 지연이 전체 장애로 번집니다. 스레드나 워커가 기다리며 막히고, 큐가 커지고, 데이터베이스 트랜잭션은 더 오래 열려 있으며 새 요청들이 타임아웃되기 시작합니다. 얼마 지나지 않아 외부 API를 사용하지 않는 페이지까지 대기 작업으로 인해 제대로 동작하지 않게 됩니다.
영향은 구체적입니다. 불안정한 신원 제공자는 가입과 로그인을 막습니다. 결제 게이트웨이 타임아웃은 결제를 멈춰 사용자가 과금 여부를 알 수 없게 만듭니다. 메시지 지연은 비밀번호 재설정과 주문 확인을 멈추게 하고, 이는 추가 재시도와 지원 티켓의 두 번째 물결을 촉발합니다.
목표는 간단합니다: 외부 실패를 격리해 핵심 워크플로가 계속 움직이게 하는 것. 예를 들어 결제는 나중에 확인하고 사용자가 주문을 완료하게 하거나, 환영 이메일이 실패해도 가입을 허용하는 식입니다.
실무적 성공 지표는 명확합니다: 제공자가 느리거나 다운일 때도 앱은 빠르고 분명하게 응답해야 하며 영향 범위는 작아야 합니다. 예를 들어 대부분의 핵심 요청은 정상 지연 예산 내에서 완료되고, 실패는 해당 API에 실제로 의존하는 기능에만 국한되며, 사용자에게는 명확한 상태(대기중, 보류, 나중에 다시 시도 등)가 표시되고, 제공자가 복구하면 자동으로 회복됩니다.
대비해야 할 실패 모드
대부분의 실패는 시기를 예측할 수는 없지만 유형은 예측 가능합니다. 미리 이름을 붙이면 무엇을 재시도하고 무엇을 중단하며 사용자에게 무엇을 보여줄지 결정할 수 있습니다.
일반적인 분류:
- 지연 급증(요청이 갑자기 10배 느려짐)
- 일시적인 서버 또는 네트워크 오류(타임아웃, 502/503, 연결 재설정)
- 속도 제한 및 할당량 초과(429, 일일 한도)
- 인증 및 권한 문제(만료된 키, 접근 권한 철회)
- 잘못되거나 놀라운 데이터(누락 필드, 잘못된 형식, 부분 응답)
모든 오류가 같은 의미는 아닙니다. 일시적 문제는 재시도할 만한 가치가 있는 경우가 많습니다(네트워크 블립, 타임아웃, 502/503, 일부 429는 대기 후 재시도). 영구적인 문제는 저절로 고쳐지지 않습니다(잘못된 자격 증명, 잘못된 엔드포인트, 권한 거부 등).
모든 오류를 똑같이 처리하면 작은 사고가 다운타임으로 커집니다. 영구적인 실패를 재시도하면 시간 낭비이고 속도 제한에 더 빨리 걸리며 백로그가 쌓여 다른 것들이 느려집니다. 반대로 일시적 실패를 절대 재시도하지 않으면 사용자가 동작을 반복해야 하고, 잠시 후에 완료될 수 있는 작업을 놓칩니다.
결제, 로그인, 비밀번호 재설정, 알림(이메일/SMS/푸시)처럼 잠시 멈추는 것이 큰 문제로 느껴지는 워크플로에 특히 주의하세요. 마케팅 API에서 2초 지연은 성가실 뿐이지만, 결제 승인에서 2초 지연은 수익을 막습니다.
유용한 테스트 질문은: "이 호출이 지금 사용자의 주요 작업을 완료하는 데 반드시 필요한가?" 입니다. 예이면 타이트한 타임아웃, 신중한 재시도, 명확한 실패 경로가 필요합니다. 아니면 큐로 옮겨 앱을 반응형으로 유지하세요.
타임아웃: 한계를 정하고 지키기
타임아웃은 더 이상 기다리지 않고 멈추는 최대 시간입니다. 명확한 한계가 없으면 한 공급자의 느려짐이 기다리는 요청을 쌓아 중요한 작업을 차단합니다.
두 가지 대기 유형을 구분하는 것이 도움이 됩니다:
- 연결 타임아웃(Connect timeout): 연결을 시도할 최대 시간
- 응답 대기 타임아웃(Read timeout): 연결 후 응답을 기다리는 최대 시간
숫자를 고르는 것은 완벽함의 문제가 아닙니다. 사람의 인내심과 워크플로에 맞추는 문제입니다.
- 사용자가 스피너를 보고 있다면 보통 빠른 답변과 명확한 다음 단계를 제공해야 합니다.
- 백그라운드 작업(예: 밤사이 송장 동기화)이라면 더 긴 시간을 허용할 수 있지만 무한히 걸리지 않도록 한계는 필요합니다.
타임아웃을 정하는 실무적 방법은 경험에서 역산하는 것입니다:
- 사용자가 얼마나 오래 기다릴 수 있는가? 언제 명확한 메시지를 보여줘야 하는가?
- 이 호출이 지금 실패하면 나중에 재시도하거나 대체 수단을 사용할 수 있는가?
- 피크 부하 때 이러한 호출이 몇 번 실행되는가?
트레이드오프는 현실적입니다. 너무 길면 스레드, 워커, DB 연결을 묶어두고, 너무 짧으면 거짓 실패를 만들어 불필요한 재시도를 유발합니다.
재시도: 장애를 악화시키지 않는 방식
재시도는 실패가 일시적일 가능성이 클 때 도움이 됩니다: 짧은 네트워크 문제, DNS 일시적 오류, 일회성 500/502/503 등. 이런 경우 두 번째 시도로 성공할 수 있고 사용자는 알아차리지 못할 수 있습니다.
위험은 재시도 폭풍입니다. 많은 클라이언트가 동시에 실패하고 함께 재시도하면 공급자(그리고 여러분의 워커)를 과부하 시킬 수 있습니다. 백오프와 지터(jitter)가 이를 방지합니다.
재시도 예산을 두면 현실적인 수준을 유지할 수 있습니다. 시도 횟수를 낮게 유지하고 총 시간을 제한해 핵심 워크플로가 다른 서비스에 걸려 멈추지 않게 하세요.
안전한 기본 재시도 레시피
- 재시도는 소수로(흔히 총 1~3회, 흐름에 따라 다름).
- 지수 백오프(exponential backoff)를 사용(예: 200ms, 500ms, 1s)하고 무작위 지터 추가.
- 재시도에 소비하는 총 시간을 제한(사용자 대기 흐름에서는 보통 몇 초).
- 모든 시도마다 개별 타임아웃을 사용하고, 시도 전체에 대해 하나의 긴 타임아웃을 사용하지 않음.
400/422 같은 예측 가능한 클라이언트 오류, 401/403 인증 문제, 404 같은 경우는 재시도하지 마세요. 이런 오류는 다시 시도해도 거의 실패합니다.
또 한 가지 방어책: POST/PUT 같은 쓰기 작업은 멱등성이 확보되어 있을 때만 재시도하세요. 그렇지 않으면 중복 청구나 중복 레코드가 발생할 수 있습니다.
멱등성: 실무에서 재시도를 안전하게 만들기
멱등성은 같은 요청을 여러 번 실행해도 최종 결과가 동일하도록 하는 것을 의미합니다. 네트워크가 끊기고 서버가 재시작하며 클라이언트가 타임아웃되는 상황에서 재시도는 정상입니다. 멱등성이 없으면 "도와주려는" 재시도가 중복을 만들고 실제 금전 문제를 야기합니다.
예를 들어 체크아웃: 결제 API가 느려 앱이 타임아웃되고 재시도하면, 첫 번째 호출이 이미 성공했더라도 재시도로 인해 두 번째 청구가 발생할 수 있습니다. 주문 생성, 구독 시작, 이메일/SMS 발송, 환불 처리, 지원 티켓 생성 같은 작업에도 동일한 위험이 존재합니다.
해결책은 멱등성 키(또는 요청 ID)를 모든 "무언가를 수행하는" 호출에 붙이는 것입니다. 이 키는 시도별이 아니라 사용자 행동별로 고유해야 합니다. 제공자(또는 자체 서비스)는 그 키를 사용해 중복을 감지하고 같은 결과를 반환하도록 해야 합니다.
멱등성 키를 헤더에 붙이는 것처럼 대충 다루지 말고 데이터 모델의 일부로 취급하세요.
운영 환경에서 통하는 패턴
사용자가 액션을 시작할 때(예: Pay 버튼 클릭) 하나의 키를 생성하고 로컬 기록과 함께 저장하세요.
각 시도에서:
- 같은 키를 보낸다.
- 받은 최종 결과(성공 응답, 실패 코드, 결제 ID 등)를 저장한다.
- 이미 기록된 결과가 있으면 동일한 결과를 반환하고 그 행동을 반복하지 않는다.
내부 호출의 "제공자(provider)" 역할을 한다면 서버 측에서도 동일한 동작을 강제하세요.
서킷 브레이커: 실패할 때 호출을 멈추기
서킷 브레이커는 안전 스위치입니다. 외부 서비스가 실패를 시작하면 일정 기간 호출을 차단해 더 많은 요청이 쌓여 타임아웃되는 것을 막습니다.
서킷 브레이커는 보통 세 가지 상태를 가집니다:
- Closed(닫힘): 요청이 정상적으로 흐름
- Open(열림): 쿨다운 기간 동안 호출 차단
- Half-open(반열림): 쿨다운 후 소수의 테스트 호출로 서비스 복구 여부 확인
브레이커가 열려 있을 때 앱은 예측 가능한 동작을 해야 합니다. 가입 중 주소 검증 API가 다운이면 주소를 받아두고 나중에 검토하도록 표시하세요. 결제 위험 점검이 다운이면 주문을 수동 검토 큐로 보내거나 해당 옵션을 임시로 비활성화하고 이유를 설명하세요.
임계값은 사용자 영향에 맞춰 선택하세요:
- 연속 오류(예: 연속 5회 실패)
- 짧은 창에서의 높은 실패율
- 많은 느린 응답(타임아웃)
- 특정 상태 코드(반복되는 503 등)
쿨다운은 짧게(몇 초에서 1분) 유지하고 반열림 테스트는 제한적으로 하세요. 목표는 먼저 핵심 워크플로를 보호하고 빠르게 복구하는 것입니다.
폴백과 큐: 앱을 사용 가능하게 유지하기
외부 API가 느리거나 다운되었을 때 목표는 사용자가 계속 진행할 수 있게 하는 것입니다. 즉 솔직한 플랜 B를 준비해야 합니다.
폴백: "충분히 좋은" 경험 선택하기
API가 제시간에 응답하지 못할 때 앱이 하는 일입니다. 캐시된 데이터 사용, 저하된 모드로 전환(비핵심 위젯 숨김, 선택적 동작 비활성화), API 호출 대신 사용자 입력 요청(수동 주소 입력), 또는 명확한 다음 단계 메시지 표시 등이 포함됩니다.
정직하게 처리하세요: 완료되지 않은 작업을 완료되었다고 표시하지 마세요.
큐: 지금이 아니면 나중에 처리
작업이 사용자 요청 내에서 반드시 끝나야 하지 않다면 큐로 밀고 빨리 응답하세요. 일반적인 후보: 이메일 발송, CRM 동기화, 보고서 생성, 분석 이벤트 포스트 등.
핵심 작업은 빠르게 실패(fail fast)하세요. API가 체크아웃(또는 계정 생성)을 완료하는 데 필요 없다면 요청을 차단하지 마세요. 주문을 수락하고 외부 호출을 큐에 넣어 나중에 조정하세요. 만약 API가 필수(예: 결제 승인)라면 사용자를 오래 기다리게 하지 말고 빠르게 실패하며 명확한 메시지를 제공하세요.
사용자가 보는 것과 내부에서 일어나는 일이 일치해야 합니다: 명확한 상태(완료, 보류, 실패), 약속(영수증 즉시, 확인은 나중에), 재시도 방법, UI상의 가시적 기록(활동 로그, 보류 배지).
속도 제한과 부하: 스스로 초래하는 장애 피하기
속도 제한은 제공자가 "너희는 호출할 수 있지만 너무 자주 하지 마"라고 말하는 방식입니다. 생각보다 빨리 걸립니다: 트래픽 급증, 동시에 실행되는 백그라운드 잡, 또는 오류를 반복하는 버그 등.
먼저 생성하는 요청 수를 제어하세요. 가능한 경우 배치 처리하고, 안전하다면 30~60초 정도 응답을 캐시하며, 클라이언트 측에서 스로틀링해 앱이 공급자보다 빠르게 폭발적으로 호출하지 않도록 하세요.
429 Too Many Requests를 받으면 속도를 늦추라는 신호로 처리하세요.
Retry-After가 제공되면 존중하세요.- 많은 워커가 동시에 재시도하지 않도록 지터를 추가하세요.
- 429에 대한 재시도는 상한을 두어 무한 루프를 피하세요.
- 반복되는 429에는 더 공격적으로 백오프하세요.
- 패턴을 알아차리도록 메트릭으로 기록하세요.
동시성도 제한하세요. 하나의 워크플로(예: 연락처 동기화)가 모든 워커 슬롯을 소모해 로그인이나 체크아웃 같은 핵심 흐름을 고갈시키면 안 됩니다. 별도 풀이나 기능별 캡을 사용하는 것이 도움이 됩니다.
단계별: 안전한 기본 통합 레시피
모든 서드파티 호출에는 실패에 대한 계획이 필요합니다. 완벽할 필요는 없습니다. 공급자가 안 좋은 날을 보낼 때 예측 가능한 동작이면 됩니다.
1) 호출 분류(지금 반드시 필요한가 vs 기다릴 수 있는가)
호출이 지금 실패하면 무엇이 일어나는지 결정하세요. 체크아웃 중 세금 계산은 필수일 수 있고, 마케팅 연락처 동기화는 보통 기다릴 수 있습니다. 이 선택이 나머지를 좌우합니다.
2) 타임아웃과 재시도 예산 설정
호출 유형별로 타임아웃을 정하고 일관되게 유지하세요. 그런 다음 재시도 예산을 정해 느린 API를 계속 두드리지 않게 하세요.
- 사용자가 기다리는 필수 작업: 짧은 타임아웃, 재시도 0~1회.
- 기다릴 수 있는 백그라운드 작업: 더 긴 타임아웃, 백오프를 가진 여러 번의 재시도.
- 영원히 재시도하지 않기: 작업당 소비되는 총 시간에 상한을 두세요.
3) 멱등성 및 추적으로 재시도 안전하게 만들기
작업이 무언가를 생성하거나 금전을 청구할 수 있으면 멱등성 키를 추가하고 요청 기록을 저장하세요. 결제 요청이 타임아웃되면 재시도가 중복 청구를 만들어선 안 됩니다. 추적은 지원팀이 "처리되었나요?"라고 물을 때도 도움이 됩니다.
4) 서킷 브레이커와 폴백 동작 추가
오류가 급증하면 공급자 호출을 짧게 중단하세요. 필수 호출에는 명확한 "다시 시도" 경로를 보여주고, 기다릴 수 있는 호출은 큐에 넣어 나중에 처리하세요.
5) 기본 모니터링 추가
지연, 오류율, 브레이커 열림/닫힘 이벤트를 추적하세요. 단일 일시적 이상 현상이 아니라 지속적인 변화에 대해 알림을 설정하세요.
작은 문제가 다운타임으로 번지는 일반적 실수
대부분의 API 장애는 처음부터 크지 않습니다. 앱이 최악의 방식으로 반응하기 때문에 커집니다: 너무 오래 기다리고, 과도하게 재시도하며, 다른 모든 것을 유지하는 동일한 워커를 묶어둡니다.
이 패턴들이 연쇄 반응을 일으킵니다:
- 잘못된 요청, 만료된 인증, 권한 문제 같은 4xx 오류까지 모두 재시도함.
- "안전하게"라는 이유로 매우 긴 타임아웃을 설정해 스레드, DB 연결, 잡 러너를 조용히 소모함.
- 멱등성 키 없이 생성 작업을 재시도해 이중 청구, 중복 출하, 반복 레코드 발생.
- 복구하지 못하거나 너무 자주 열렸다 닫히는 잘못 구성된 서킷 브레이커.
- 부분적 장애를 전체 장애로 취급해 해당 기능만 저하시키지 않음.
작은 수정으로 큰 장애를 예방할 수 있습니다: 일시적일 가능성이 있는 오류(타임아웃, 일부 429, 일부 5xx)만 재시도하고 백오프와 지터로 시도 횟수 제한; 타임아웃은 짧고 의도적으로 설정; 생성/청구 작업엔 멱등성 요구; 부분적 장애를 염두에 둔 설계.
배포 전 빠른 체크리스트
통합을 프로덕션에 배포하기 전에 실패 관점으로 빠르게 점검하세요. 핵심 워크플로(가입, 체크아웃, 메시지 전송)와 관련된 항목에 대해 "예"로 대답할 수 없다면 릴리즈 차단으로 간주하세요.
- 시간 제한이 명확히 설정되어 있는가(연결 타임아웃 및 읽기/응답 타임아웃).
- 재시도는 제한되어 있는가(작은 재시도 예산, 백오프, 지터, 총 시간 상한).
- 재시도는 실무적 동작에 대해 안전한가(멱등성 키나 명확한 중복 제거 검사).
- 브레이커와 플랜 B가 있는가(폴백, 저하 모드, 큐).
- 문제를 조기 감지할 수 있는가(공급자 및 엔드포인트별 지연, 오류율, 종속성 상태).
결제 공급자가 타임아웃되기 시작하면 올바른 동작은 "체크아웃이 여전히 로드되고, 사용자에게 명확한 메시지가 표시되며, 무한히 대기하지 않는다"이지, "모든 것이 타임아웃될 때까지 멈춘다"가 아닙니다.
예시: 공급자가 불안정할 때 체크아웃 보호하기
체크아웃이 세 가지 서비스를 호출한다고 가정해보세요: 카드를 청구하는 결제 API, 세금을 계산하는 세금 API, 영수증을 보내는 이메일 API.
결제 호출만 동기화가 필수입니다. 세금이나 이메일의 문제로 구매가 막혀선 안 됩니다.
세금 API가 느릴 때
세금 API가 가끔 8~15초 걸린다면 체크아웃이 기다리면 사용자가 장바구니를 버리고 앱은 워커를 묶습니다.
더 안전한 흐름:
- 하드 타임아웃 설정(예: 800ms~2s)하고 빠르게 실패하도록 함.
- 안전한 경우에만 한 번만 재시도하고 지터를 사용.
- 타임아웃이 나면 구매자의 지역에 대해 캐시된 요율이나 마지막 알려진 표를 사용.
- 법적으로 캐시된 요율을 사용할 수 없다면 주문을 "세금 보류"로 두고 재계산을 큐에 넣음.
결과: 세금 공급자가 느릴 때 장바구니 포기와 주문 정체가 줄어듭니다.
이메일 API가 다운일 때
영수증 이메일은 중요하지만 결제 캡처를 막아선 안 됩니다. 이메일 API가 실패하면 몇 번의 빠른 실패 후 서킷 브레이커가 열리고 짧은 쿨다운 동안 호출을 중단해야 합니다.
이메일을 인라인으로 보내지 말고 멱등성 키(예: order_id + email_type)와 함께 "영수증 전송" 작업을 큐에 넣으세요. 공급자가 다운되면 큐가 백그라운드에서 재시도하고 고객은 여전히 성공적으로 구매한 것을 보게 됩니다.
결과: 누락된 확인으로 인한 지원 티켓이 줄고, 비결제 이유로 체크아웃이 실패해 수익을 잃지 않습니다.
다음 단계: 앱 전반에 안전한 설정을 롤아웃하기
가장 문제가 되는 워크플로우 하나(체크아웃, 가입, 청구)를 선택해 기준 통합으로 삼고 같은 기본값을 복사해 다른 곳에 적용하세요.
간단한 롤아웃 순서:
- 타임아웃을 설정하고 빠르게 실패하며 명확한 오류를 제공.
- 재시도를 백오프와 함께 추가하되 재시도 가능한 오류에만 적용.
- 재시도가 이중 청구나 중복 생성을 만들지 않도록 멱등성 추가.
- 서킷 브레이커 추가로 나쁜 공급자가 핵심 워크플로를 막지 못하게 함.
기본값을 문서화하고 단순하게 유지하세요: 하나의 연결 타임아웃, 하나의 요청 타임아웃, 최대 재시도 횟수, 백오프 범위, 브레이커 쿨다운, 재시도 가능 규칙 등.
다음 워크플로로 확장하기 전에 실패 드릴을 실행하세요. 테스트 환경에서 타임아웃을 강제로 발생시키거나 공급자를 차단하고 사용자가 유용한 메시지를 보는지, 폴백 경로가 작동하는지, 큐에 쌓인 재시도가 영원히 쌓이지 않는지 확인하세요.
신제품을 빠르게 만드는 팀이라면 이 신뢰성 기본값을 재사용 가능한 템플릿으로 만드는 것이 가치가 있습니다. Koder.ai (koder.ai)를 사용하는 팀의 경우, 타임아웃, 재시도, 멱등성, 브레이커 규칙을 한 번 정의한 뒤 새 서비스 전반에 동일한 패턴을 적용하는 경우가 많습니다.
자주 묻는 질문
느린 타사 API가 내 앱을 중단시킬 수 있는 이유는 무엇인가요?
모든 호출에 연결 및 읽기 제한 시간을 명시적으로 설정하세요. 사용자 대면 흐름에는 짧은 제한 시간을 정하고, 그 후 명확한 결과를 반환하거나 필수적이지 않은 작업을 큐로 옮기세요.
어떤 API 오류를 재시도해야 하나요?
타임아웃, 연결 재설정, 일부 5xx 오류는 빠르게 해소될 수 있으므로 재시도하세요. 잘못된 요청, 잘못된 자격 증명, 권한 오류 또는 존재하지 않는 엔드포인트는 재시도하지 마세요.
API 요청은 몇 번 재시도해야 하나요?
재시도 횟수는 적게 유지하세요. 일반적으로 총 1~3회 시도면 충분합니다. 무작위 지터를 포함한 지수 백오프를 사용하고 재시도에 쓰는 총 시간을 제한하세요.
결제 요청이 타임아웃될 때 중복 청구를 막으려면 어떻게 해야 하나요?
레코드 생성, 메시지 전송, 환불 처리 또는 결제를 수행하는 작업에는 멱등성 키를 사용하세요. 한 번의 사용자 작업에서 발생한 모든 시도에 같은 키를 재사용하세요.
서킷 브레이커는 무엇을 하나요?
서킷 브레이커는 반복적인 실패나 타임아웃이 발생한 뒤 호출을 일시적으로 중단합니다. 워커를 보호하고, 제한된 테스트 요청을 다시 보내기 전에 제공업체가 복구할 시간을 줍니다.
어떤 작업을 백그라운드 큐로 옮겨야 하나요?
선택 사항인 호출을 분리해 결제와 로그인이 빠르게 응답하도록 하세요. 사용자 요청 중에 기다리지 말고 영수증 이메일, CRM 업데이트, 분석 작업을 큐에 넣으세요.
앱은 429 속도 제한 응답을 어떻게 처리해야 하나요?
제공업체가 Retry-After 값을 제공하면 이를 따르고, 동시성을 줄이며, 재시도 전에 지터를 추가하세요. 앱 호출 수를 줄이도록 안전한 읽기 요청은 캐시하거나 일괄 처리하세요.
외부 서비스가 실패했을 때 사용자에게 무엇을 보여 줘야 하나요?
실제 상태를 보여 주세요. 완료됨, 처리 대기 중 또는 실패입니다. 결제를 다시 시도하거나 나중에 처리 대기 중인 주문을 확인하는 것처럼 사용자가 취할 수 있는 실질적인 다음 단계를 안내하세요.
타사 API에 대해 무엇을 모니터링해야 하나요?
각 제공업체와 엔드포인트별로 지연 시간, 오류율, 타임아웃 비율, 속도 제한 응답, 서킷 브레이커 이벤트를 추적하세요. 문제가 커지기 전에 발견할 수 있도록 지속적인 변화에 알림을 설정하세요.
출시 전에 API 통합을 어떻게 테스트해야 하나요?
출시 전에 타임아웃, 부분 응답, 429, 5xx 오류, 반복된 쓰기 요청을 테스트하세요. 대체 처리 방식이 작동하고, 큐에 넣은 작업이 제한된 범위를 유지하며, 재시도가 작업을 중복하지 않는지 확인하세요.