기술

9일 묵은 차단, 알고 보니 우리가 매일 갱신하고 있었습니다

2026.08.137분 읽기

외식 프랜차이즈 ERP를 운영하며 배달 플랫폼의 매출 데이터를 크롤링으로 수집하고 있습니다. 어느 날 한 플랫폼이 특정 매장들의 매출 조회에 '과도한 요청으로 이용이 일시 제한되었습니다'라는 자체 에러를 반환하기 시작했습니다. 3개 계정, 5개 매장이 영향권이었습니다.

하루 이틀이면 풀리겠거니 했습니다. 그런데 9일이 지나도 그대로였습니다. 자동화 크롤러만 막힌 것도 아니었습니다. 사람이 브라우저로 직접 로그인해서 같은 화면에 들어가도 똑같이 막혔습니다.

결론부터 말하면, 차단을 9일간 유지시킨 것은 플랫폼이 아니라 우리 쪽 복구 장치였습니다. 그리고 해결은 코드 한 줄 추가 없이 설정 하나를 바꾸는 것으로 끝났습니다. 그 과정을 순서대로 정리합니다.


반사적으로 재로그인 코드부터 짰습니다

차단을 처음 인지했을 때 가장 먼저 나온 가설은 세션 문제였습니다. 인증이 꼬였거나 세션이 오염됐으니 새로 로그인하면 풀리지 않겠느냐는 것입니다. 그래서 403 계열 에러가 나면 재로그인 후 1회 재시도하는 코드를 작성했습니다.

그런데 배포 전에 확인한 사실 하나가 방향을 통째로 바꿨습니다. 차단된 계정의 같은 세션으로 정산 조회와 리뷰 조회는 정상 동작했습니다. 세션이나 IP가 차단됐다면 다른 기능도 함께 막혀야 합니다. 매출 조회만, 그것도 특정 매장에서만 막힌다는 것은 차단의 단위가 세션이 아니라 매장 키라는 뜻이었습니다.

이 판별 하나로 재로그인 재시도 코드는 무의미로 판정됐습니다. 스코프를 오판하면 처방 자체가 무의미해집니다. 같은 세션으로 다른 기능이 되는가, 다른 IP에서는 되는가 — 이 두 질문이 차단 대응의 출발점이라는 것을 이때 배웠습니다.

다운로드.png


차단이 9일간 안 풀린 진짜 이유

매장 단위 throttle이라면 통상 반나절에서 하루 정도 쉬면 풀립니다. 그런데 9일째 그대로였습니다. 로그를 시간순으로 늘어놓고 나서야 이유가 보였습니다.

우리 크롤러에는 실패한 매장을 다시 긁는 자동 재크롤 배치가 있었습니다. 이 배치가 매시간 돌면서 차단된 매장을 하루 30~102회 재요청하고 있었습니다. 어떤 매장은 17~53시간 동안 쉼 없이 두드려지는 마라톤 상태였습니다.

rate-limit의 throttle 창은 마지막 요청 시점을 기준으로 갱신됩니다. 하루 30번 넘게 두드려지는 매장에게 '하루 휴지'는 단 한 번도 실행된 적이 없었습니다. 실패를 복구하려고 만든 장치가 차단을 유지시키는 자기 강화 루프였습니다. 차단이 안 풀린 게 아니라, 풀릴 기회를 우리가 매일 없애고 있었습니다.

다운로드 (1).png

rate-limit 차단의 유일한 복구는 백오프다. 재시도·재로그인·세션 리셋은 throttle 창만 갱신한다.


처방은 코드가 아니라 설정 하나였습니다

재크롤 배치의 빈도를 절반으로 줄였습니다. 매시간에서 2시간 간격으로, 하루 16회에서 8회로. 변경한 것은 cron 표현식 하나뿐이고, 코드는 한 줄도 추가하지 않았습니다.

며칠 관찰 후 5개 매장 전부에서 차단이 해제됐고, 막혀 있던 기간의 매출 데이터는 백필로 채웠습니다. 백오프는 필연적으로 데이터 공백을 만들기 때문에, 해제 후 백필 절차가 세트로 준비돼 있어야 합니다.

빈도를 얼마나 줄여야 하는지에 대한 문서화된 한도는 없었습니다. 플랫폼마다 다르고, 며칠 단위 실측 관찰로만 알 수 있습니다. 매장 단위 한도는 타 크롤러와의 합산 트래픽일 수도 있어서, 우리만 조심해도 안 풀릴 가능성까지 감안해야 했습니다.

다운로드 (2).png

다른 도메인에서도 같은 구조를 만난 적이 있습니다. 외부 LLM API가 429를 뱉기 시작했을 때도, 결론은 더 두드리기가 아니었습니다.


같은 '접근 거부'라도 부류가 다르면 대응이 정반대입니다

이번 사건을 정리하면서, 표면적으로 같아 보이는 접근 거부가 실제로는 두 부류라는 것을 대응표로 문서화했습니다.

구분

매장 단위 rate-limit

엣지(CDN/WAF) 전면 차단

막는 주체

플랫폼 애플리케이션단

엣지(CDN/WAF)단

차단 범위

특정 매장 키

IP·브라우저 전체

사람도 막히나

막힌다(같은 화면에서)

브라우저 접속 자체가 막힌다

대응

해당 매장만 skip, 빈도 축소

배치 전체 중단 + 쿨다운

부류가 다르면 대응이 정반대입니다. 매장 단위 rate-limit에 배치 전체를 멈추면 멀쩡한 매장의 수집까지 버리는 것이고, 전면 차단에 매장 skip으로 대응하면 차단을 더 키웁니다. 판별 기준을 노하우 문서에 남겨서, 다음 차단은 판별부터 시작하도록 했습니다.


후일담 — 폐기하려던 코드가 살아남았습니다

스코프 판별에서 무의미 판정을 받았던 재로그인 재시도 코드는 폐기 방향이었습니다. 그런데 다른 배포에 섞여 그대로 라이브에 나갔습니다.

열흘간 지켜본 결과는 무사고였습니다. rate-limit 에러는 별도 분류로 분리돼 있어 재로그인 로직을 타지 않았고, 순수 세션 만료 케이스에서는 오히려 제 역할을 했습니다. 폐기 예정이던 코드를 실측 데이터로 재평가해 유지로 확정했습니다. 폐기냐 유지냐의 판단도 도그마가 아니라 데이터로 하게 된 사례입니다.


차단을 만났을 때 확인하는 것들

스코프 판별이 먼저다 — 같은 세션으로 다른 기능이 되는가, 다른 IP에서는 되는가. 스코프가 처방을 결정한다.

실패 재처리 배치를 의심하라 — 실패 원인이 '과다 요청'인 건은 재처리 대상에서 빼거나 지수 백오프를 태운다.

복구는 덜 두드리는 것이다 — 재시도·재로그인·세션 리셋은 throttle 창만 갱신한다.

빈도 축소 후에는 며칠 단위 관찰이 필요하다 — 문서화된 한도는 없고 실측으로만 알 수 있다.

백오프와 백필은 세트다 — 쉬는 동안 생긴 데이터 공백을 채울 절차를 함께 준비한다.

에러 부류 구분 기준을 문서로 남긴다 — 같은 표면의 에러라도 대응이 정반대일 수 있다.

9일 걸린 이번 차단에서 실제로 작성한 코드는 0줄, 변경한 설정은 1줄이었습니다. 다음 차단이 오면 우리는 코드가 아니라 판별표부터 폅니다.

#운영의기술#ratelimit#백오프#크롤링#재시도전략#장애대응#배치운영#에러분류