為什么限流时要给出明确的狀態碼
当站点压力上升,服務器常用的做法有两種:一是让請求挂到超时或返回 500,二是主動返回 503 或 429。前者在日誌里表現為连接中断或服務错誤,蜘蛛只能按自己的退避策略重试;後者是明确告诉對方「現在不行,過一會儿再来」。對抓取节奏来说,主動返回带 Retry-After 的 503 通常比让請求撞到超时更可控,因為它把等待時間變成了双方都能讀到的约定。
503 與 429:先分清两種信号
两者语义不同。503 Service Unavailable 表示服務临时不可用,常见于维護窗口、後端過载、下游依赖故障;429 Too Many Requests 表示請求频率超出限制,更适合针對單一来源做速率控制。選错狀態碼不會让問题消失,只會让後續排查失去线索:看到 429 會先想频率,看到 503 會先想服務本身。
Retry-After 的寫法與常见坑
Retry-After 支持两種格式,一種是以秒為單位的整數,一種是 HTTP-date 時間戳。秒數寫法简單,不依赖双方时钟;HTTP-date 可讀性好,但要求服務器时钟准确,否則可能给出已经過去的時間,或過遠的未来時間。
- 秒數按實际恢复時間估算,维護窗口十分钟就寫 600,不要随手寫 86400。
- 返回 503 时同时给出 Retry-After,蜘蛛更容易按你给的节奏回訪;只给 503 不给该头,回訪間隔由對方决定。
- HTTP-date 使用 GMT 格式,不要和本地时区混用,日誌时区與服務时区也要對齐後再判断。
- 長時間维持一個很大的 Retry-After,等于主動压低抓取频次,恢复後不會立刻回到原来的节奏。
哪些场景适合用 503
- 計划内维護:發布、迁移、資料库變更,预計几十分钟内恢复。
- 突發流量:源站被打满,先挡住一部分請求,保住核心頁面的可用性。
- 下游依赖故障:缓存、搜尋服務或資料库不可用造成的临时错誤。
也要说清楚不适合的场景:長期下线的栏目、确定不再提供的内容,應该用 404 或 410 让它登出抓取队列,而不是一直用 503 拖着。把 503 当软刪除使用,入口會長期占用抓取预算,恢复後也难以判断该目錄是否還有價值。
排查顺序
- 先看訪問日誌里 503 的比例和分布,判断是全站、某個目錄還是某個接口。
- 检查响應是否带有 Retry-After,格式是秒還是 GMT 時間,數值是否與预期恢复時間相符。
- 確認 CDN 或反向代理有没有把 503 当成可缓存响應,避免恢复後仍返回舊狀態。
- 核對维護頁是否返回 200 但内容為空,這種「假 200」會让蜘蛛把空頁当正常頁面處理。
- 观察恢复後的回訪曲线,看抓取频次是否逐步回升,而不是長時間停在低谷。
和抓取节奏的配合
503 本身不是惩罚,但持續時間、覆盖范围和出現频率會影响蜘蛛對站点的判断。短时、范围明确、带 Retry-After 的 503 通常影响有限;長時間、全站、没有說明的 503 則可能让抓取频次下降,恢复後需要一段時間才能回到原来的水平。如果只是希望某個目錄少被抓,優先考虑 robots.txt 規則或内鏈收敛,而不是靠 503 制造障碍。限流應该解决真實的资源問题,而不是当作長期的流量開關。
狀態碼是寫给抓取方看的說明书。寫清楚「現在不行、什么时候再来」,比让請求撞到超时更有助于恢复後的抓取回到正常节奏。