五类 HTTP 状态码及您在生产环境中实际会遇到的代码。[ /caption]
您的呼叫器在凌晨2点响起,告警负载中带有状态码。接下来做什么几乎完全取决于看到的是哪个状态码。
这是大多数 HTTP 状态码指南忽略的部分。它们列出定义,将代码分为五组,然后停止。作为术语表有用,但当真实端点抛出502错误且高管询问为何结账功能失效时,就不那么有用了。
本指南涵盖您最常见的十个代码,以及一些值得一提的代码。对每个代码:它的含义,通常触发它的生产场景,以及优先检查什么。目标是缩短“我看到了代码”到“我知道该修复什么”之间的时间。
什么是 HTTP 状态码?
HTTP 状态码是服务器在每个响应中返回的三位数字。它告诉客户端请求是成功、失败还是需要重定向。您会在各处看到它们:浏览器的 DevTools 网络标签、负载均衡器日志、监控告警、CDN 仪表板。本指南关注那些真正让人醒来的状态码。
HTTP 状态码的五大类
状态码的首位数字表示响应类别:
- 1xx 信息性。日常工作中很少见。主要用于协议协商(100 Continue,101 Switching Protocols 用于 WebSocket 升级)。
- 2xx 成功。请求成功。200 是默认;201 表示资源已创建;204 表示成功但无响应体。
- 3xx 重定向。资源位于其他位置。浏览器和爬虫会自动跟随直到限制。
- 4xx 客户端错误。请求有误。错误的 URL,缺失身份认证,被阻止的权限,格式错误的请求体。
- 5xx 服务器错误。请求无误,服务器未能完成请求。
4xx 和 5xx 的区分对于故障排查最重要。4xx 表示“调用方出了错”,5xx 表示“我们出了错”。前者交给调用端解决,后者交由您处理。
完整枚举请参见 Dotcom-Monitor 维基的完整 HTTP 状态码参考,列出了规范中定义的所有代码。本指南剩余部分聚焦于实际告警中出现的代码。
最常见的十个 HTTP 状态码
200 OK
服务器处理了请求并返回了预期响应。健康生产环境中,绝大多数请求希望看到这个代码。
注意:200 OK 并不代表页面正确。JavaScript 可能会静默失败,渲染空白页。API 可返回200但包含错误体。登录表单在 200 响应中可能显示“凭据无效”。仅凭状态码无法发现这些,最好配合真实浏览器检查(稍后详述)。
301 Moved Permanently
资源永久换了新 URL。浏览器会积极缓存这个重定向,搜索引擎传递大部分链接权重。
用途:网站迁移后的URL变更,HTTP切换到HTTPS,合并重复路径,废弃旧路径。一旦301生效并被缓存,回滚很痛苦——浏览器和爬虫会持续访问新地址好几个星期。
302 Found (Temporary Redirect)
资源临时位于别处。浏览器不给予缓存,搜索引擎不完全传递链接权重。
注意:302用得过多。框架默认辅助函数经常返回302,但如果是永久变更,应使用301。需保持 HTTP 方法不变(POST 仍为 POST)时,用 307 或 308。Google 最终会把持续的 302 当作 301,但“最终”不是策略。
400 Bad Request
服务器无法解析请求。格式错误的 JSON、无效请求头、超大载荷、违反模式。
优先检查:请求体。API 端点中突然激增的400通常表示客户端发送了错误格式——消费方部署变更、您这边模式变更,或第三方接口升级格式。将请求负载与之前的版本做差异比较。
401 Unauthorized
请求没有凭证,或凭证被拒绝。名称容易误导——问题在认证,而非授权。
优先检查:Token。先前正常的端点突然出现大量 401,通常是 token 过期,签名密钥变更,OIDC 提供商故障,或有人改了 audience 声明。若 API 监控发现 401 代替了 200,认证层通常是罪魁。
403 Forbidden
凭证有效,但调用方无访问权限。问题在授权而非身份认证。
优先检查:权限和基础设施规则。403 出现时往往是 IAM 策略变更、WAF 规则阻断合法流量、CDN 访问策略过严,或功能开关错误分配给用户。如果 403 正好在部署后出现,优先检查策略和配置差异而非应用代码。
404 Not Found
服务器理解了请求,但该 URL 无资源。史上最著名的状态码之一。
分两种情况区分:
- 偶发404,如拼写错误、旧书签、爬虫探测漏洞,这些属于背景噪音。
- 部署后大量404,说明发布有问题——路由丢失、构建产物缺失,或路径变更未做重定向。应回滚或推热修复。
长期存在于索引中的404最终会被谷歌剔除,canonical页返回404也会有 SEO 影响。
修复办法
快速路径:页面更改,做旧网址到新网址的301重定向,保证用户和爬虫访问正确地址。页面确实不存在,真返回404或410,不要模糊地重定向到主页。
根本修复:审计404来源。内链坏链需在源头修复;部署引起的路由缺失推热修;路径迁移错误做映射。定期爬虫自己站点,确保在谷歌发现死链前发现。
500 Internal Server Error
服务器遇到未捕获异常。是最通用的5xx错误。告知“出了问题”,但不说明具体什么。
优先检查:应用日志。每个500都有堆栈信息—没有的话说明日志有问题,不是代码。常见原因:新发布代码路径未捕获异常,下游依赖返回异常结构,数据库连接池耗尽,内存不足导致重启。生产接口持续500应触发值班报警。
修复办法
快速路径:如果500在发布后几分钟出现,先回滚。部署上线引起的500初步都认为是部署问题。
根本修复:读堆栈修补失败代码,添加回归测试防止复发。若因资源限制(连接池、内存、文件句柄),提升限制,添加告警避免未来爆满。
502 Bad Gateway
代理、负载均衡或 CDN 从上游服务器收到了无效响应,代理本身正常,背后的上游不正常。
优先检查:上游健康状态。常触发因素:应用容器崩溃但负载均衡仍路由,超时未响应,K8s pod CrashLoopBackOff,Nginx worker 配置错误,代理与上游连接重置。502 是分层架构的高信号代码,说明边缘节点没问题,问题出在下一跳。
修复办法
快速路径:重启或替换不健康的上游实例,确认负载均衡健康检查正确移除死节点。
根本修复:找出上游返回错误的原因。检查代理超时是否小于上游响应,Pod 是否持续崩溃,连接两端keep-alive设置是否匹配。
503 Service Unavailable
服务器暂时无法处理请求。容量耗尽、维护模式、自动扩缩器仍在启动。
优先检查:资源饱和和速率限制。流量激增时503多半是扩缩器跟不上或达到连接限制。稳定状态下的503通常是进程维护或队列堆积。有些平台将上游WAF或反爬系统限速也返回503,判断前先检查这点。
修复办法
快速路径:返回503并带有 Retry-After 头,让守规矩的客户端和爬虫退避,不要持续重打给吃力的服务器。PHP 示例:
http_response_code(503);
header('Retry-After: 60');
根本修复:找出饱和资源:数据库连接、工作池、自动扩缩极限,解除瓶颈。若为 CDN 或 WAF 限速,提升阈值或加白名单。
其他值得了解的状态码
上述十个涵盖了大部分生产流量。但还有一些代码在真事故中出现频率足够,值班工程师应当一看即懂。
- 304 Not Modified。缓存资源仍有效时发送。CDN 前置流量中常见。304减少说明缓存策略变动,导致使用更多源站带宽。
- 307 Temporary Redirect。类似302,但保留HTTP方法。POST还是POST。重定向表单提交或非幂等API调用时用它。
- 308 Permanent Redirect。类似301,但保留HTTP方法。API端点永久移动时现代选择,特别是那些处理POST、PUT、PATCH、DELETE请求的。
- 429 Too Many Requests。触发速率限制。可能是被上游API限流,或自己限流他人。检查
Retry-After头并配合遵守。 - 504 Gateway Timeout。代理放弃等待上游响应。区别502,上游未返回错误响应,而是超时无响应。通常是长查询、工作线程冻结或下游API慢。
301 vs 302 vs 307 vs 308
这四个重定向代码常被混淆。区别在于是否永久移动,及HTTP方法是否保留。
| 行为 | 301 | 302 | 307 | 308 |
|---|---|---|---|---|
| 是否永久 | 永久 | 临时 | 临时 | 永久 |
| 是否保留方法 | 不保证 | 不保证 | 是 | 是 |
| 浏览器缓存 | 积极缓存 | 不缓存 | 不缓存 | 缓存 |
| 传递链接权重 | 大部分 | 有限 | 有限 | 大部分 |
| 适用场景 | 永久 URL 变更 | 短期改变 | 表单或 POST 重定向 | API 端点永久移动 |
页面永久移动用301,表单提交或非幂等API调用临时移动用307,永久移动用308。
完整 HTTP 状态码参考
上面提及的代码覆盖了几乎所有实际告警。对那些季度才遇见一次需要查询的非典型代码,这里列全标准及众多基础设施厂商的非标准代码。
1xx 信息性
服务器接收请求且继续处理。应用日志中少见,因大多数客户端和代理透明处理。
| 代码 | 含义 |
|---|---|
| 100 | 继续(Continue) |
| 101 | 切换协议(Switching Protocols) |
| 102 | 处理中(Processing) |
| 103 | 早期提示(Early Hints) |
2xx 成功
请求已接收、理解并接受。200最常见;其他用于API、部分内容、WebDAV或批处理操作。
| 代码 | 含义 |
|---|---|
| 200 | 成功(OK) |
| 201 | 已创建(Created) |
| 202 | 已接受(Accepted) |
| 203 | 非权威信息(Non-Authoritative Information) |
| 204 | 无内容(No Content) |
| 205 | 重置内容(Reset Content) |
| 206 | 部分内容(Partial Content) |
| 207 | 多状态(Multi-Status) |
| 208 | 已汇报(Already Reported) |
| 226 | 实例操作已使用(IM Used) |
3xx 重定向
资源位于其他地址,或缓存内容仍有效。301和302占主导,其他针对API(307/308 保留方法)和缓存流程(304 节省源站带宽)。
| 代码 | 含义 |
|---|---|
| 300 | 多重选择(Multiple Choices) |
| 301 | 永久移动(Moved Permanently) |
| 302 | 暂时找到(Found) |
| 303 | 查看其他位置(See Other) |
| 304 | 未修改(Not Modified) |
| 305 | 使用代理(已弃用)(Use Proxy) |
| 306 | 切换代理(未用)(Switch Proxy) |
| 307 | 临时重定向(Temporary Redirect) |
| 308 | 永久重定向(Permanent Redirect) |
4xx 客户端错误
请求错误。大多数代码你都见不到,常用几码每天都有出现。知道罕见码的存在,避免遇到418或451时无从查起。
| 代码 | 含义 |
|---|---|
| 400 | 错误请求(Bad Request) |
| 401 | 未授权(Unauthorized) |
| 402 | 需付款(Payment Required) |
| 403 | 禁止访问(Forbidden) |
| 404 | 未找到(Not Found) |
| 405 | 方法不允许(Method Not Allowed) |
| 406 | 不可接受(Not Acceptable) |
| 407 | 代理认证要求(Proxy Authentication Required) |
| 408 | 请求超时(Request Timeout) |
| 409 | 冲突(Conflict) |
| 410 | 已删除(Gone) |
| 411 | 需要长度(Length Required) |
| 412 | 先决条件失败(Precondition Failed) |
| 413 | 载荷过大(Payload Too Large) |
| 414 | URI过长(URI Too Long) |
| 415 | 不支持的媒体类型(Unsupported Media Type) |
| 416 | 范围不可满足(Range Not Satisfiable) |
| 417 | 期望失败(Expectation Failed) |
| 418 | 我是一个茶壶(I’m a teapot) |
| 421 | 错误导向请求(Misdirected Request) |
| 422 | 不可处理的实体(Unprocessable Content) |
| 423 | 已锁定(Locked) |
| 424 | 依赖失败(Failed Dependency) |
| 425 | 过早(Too Early) |
| 426 | 需要升级(Upgrade Required) |
| 428 | 需要先决条件(Precondition Required) |
| 429 | 请求过多(Too Many Requests) |
| 431 | 请求头字段过大(Request Header Fields Too Large) |
| 451 | 因法律原因不可用(Unavailable For Legal Reasons) |
5xx 服务器错误
请求本身没错,服务器遇到错误。最容易触发告警。
| 代码 | 含义 |
|---|---|
| 500 | 服务器内部错误(Internal Server Error) |
| 501 | 未实现(Not Implemented) |
| 502 | 错误网关(Bad Gateway) |
| 503 | 服务不可用(Service Unavailable) |
| 504 | 网关超时(Gateway Timeout) |
| 505 | HTTP版本不支持(HTTP Version Not Supported) |
| 506 | 变体也协商(Variant Also Negotiates) |
| 507 | 存储不足(Insufficient Storage) |
| 508 | 检测到循环(Loop Detected) |
| 510 | 未扩展(Not Extended) |
| 511 | 网络认证要求(Network Authentication Required) |
非标准和厂商代码
Cloudflare、Nginx、微软及 Akamai 在其基础设施层出现错误时返回标准外代码。需识别,以便判断故障在边缘还是源站。
| 代码 | 含义 |
|---|---|
| 419 | 认证超时 |
| 420 | 请冷静 / 方法失败 |
| 440 | 登录超时(微软) |
| 444 | 无响应(Nginx) |
| 449 | 请重试(微软) |
| 450 | 被 Windows 家长控制阻挡 |
| 460 | 客户端关闭连接 |
| 494 | 请求头过大(Nginx) |
| 495 | SSL 证书错误(Nginx) |
| 496 | 需要 SSL 证书(Nginx) |
| 497 | HTTP 请求发送到 HTTPS 端口 |
| 498 | 无效 Token |
| 499 | 客户端关闭请求(Nginx) |
| 509 | 带宽限制超标 |
| 520 | 未知错误(Cloudflare) |
| 521 | 网站服务器宕机(Cloudflare) |
| 522 | 连接超时(Cloudflare) |
| 523 | 源站无法访问(Cloudflare) |
| 524 | 发生超时(Cloudflare) |
| 525 | SSL 握手失败(Cloudflare) |
| 526 | 无效 SSL 证书(Cloudflare) |
| 527 | Railgun 错误(Cloudflare) |
| 529 | 站点过载 |
| 530 | 站点冻结 / 源站 DNS 错误 |
| 561 | 未授权(Akamai) |
| 598 | 网络读取超时 |
| 599 | 网络连接超时 |
未列出的代码区间(104-199、209-225、227-299、309-399、432-450、452-499、512-599)都是未分配、弃用或预留给厂商的。视为厂商特定代码,参考基础设施文档。
监控真正应触发告警的代码
60多个代码中,大多数生产系统阈值触发的仅有少数:
- 200——基线比例,突然下降说明存在其他问题。
- 301、302、307、308——重定向数量。激增可能意味着路由配置错误或部署导致 canonical URL 断裂。
- 400——请求格式错误。通常是消费端变更。
- 401、403——认证和权限失败。通常是 token、IAM 或 WAF 变动。
- 404——资源缺失。偶发当背景噪音,看作突增时是发布问题。
- 408——客户端请求超时。持续出现时值得告警,表示下游调用缓慢。
- 429——限流。可能是上游API限流,或者自我限流过严。
- 500、502、503、504——应用问题、上游问题、容量和网关超时故障,应触发值班告警。
- 520-526——Cloudflare 边缘错误。若站点靠 Cloudflare,这些是关键故障信号,定位失败在边缘到源站链路。
其余代码建议记录,但极少触发告警。
如何检查页面的 HTTP 状态码
在采取行动前需先看到状态码。有三种办法,从最快到最彻底:
Chrome DevTools
- 打开页面。
- 右键任何地方选择“检查”,切换到网络(Network)标签。
- 刷新页面,首个文档请求在状态(Status)列显示代码。
命令行
发起只返回响应头的请求,避免下载响应体:
curl -I https://example.com
响应第一行即状态码,例如 HTTP/2 200。
规模化
单次检查只知当前状态,捕获不到凌晨3点发生后又消失的失败。要捕获间歇故障,需多地域定时检查,这正是 合成监控 的职责。
当 200 OK 欺骗你时
某电商团队周二上午11点接到页报警。转化率下降80%。查看可用性仪表盘,所有端点皆绿,状态码全是200,所有区域均回报正常。
网站其实不可用。40分钟前发布了一个导致结账页 JavaScript 抛异常的包。HTML渲染正常,服务器返回了200,状态码监控看到200,未触发告警。用户看到空购物车并流失。
这就是纯状态码监控捕捉不到的失败模式。解决方案是分层的:
- 真实浏览器检查关键用户路径——首页、搜索、商品、购物车、结账。真实浏览器执行JS,能暴露 curl 样式检查捕捉不到的客户端错误。
- 关注响应体信号:关键词出现、元素可见性、预期结构。别只信状态码。
- 关联部署与监控:任何在发布后15分钟内从绿变红的检查应自动标记该发布。事后诊断半数时间花在找变更,监控系统已知晓。
什么是软404?
此问题一种常见表现:软 404。页面返回200成功码,但提示内容不存在——成功码下的“页面未找到”信息。谷歌建议直接返回真实 404 或 410,避免软404浪费爬取预算并混淆索引真实页面。
纯状态码监控捕获不了软404,原因同捕获不了坏结账页:状态码为200。真实浏览器检查并验证响应体内容(查找预期真实内容或未找到信息)可有效检测。
HTTP 状态码如何影响 SEO
搜索引擎用状态码决定抓取、索引页面及返回频率。三条规律:
- 4xx 代码逐渐削弱索引。多次爬取返回404的页面将被剔除。删除页面应使用301重定向,别让其404。
- 5xx 代码减缓爬取,损害排名。Googlebot 把持续5xx当作网站不健康,爬取速率下降,索引放缓,排名可能下滑。
- 301与302区别重要。301传递链接权重,302视为暂时,可能不传。永久更改应用301。
实用结论:5xx错误不仅仅关乎可用性,而是随着持续造成堆叠的 SEO 问题。DNS、TCP、TLS 和 HTTP 错误各有不同SEO成本,了解故障所在层可加速排查。
从状态码到首次调查步骤的简单故障排查路径。[ /caption]
如何监控 HTTP 状态码而不被告警淹没
每个监控 HTTP 流量的团队最终都会遇到同样问题:告警太多,信号不足。几个做法能让状态码监控保持有用而不是嘈杂。
按比率告警,不是单次请求。一个500是噪音,五十个500五分钟内是事故。配置阈值基于基线流量。
分离用户端点与内部端点。结账API的500应触发告警,没人访问的管理端点500可等上班时间处理。
从用户地理位置来测试。单中心检测抓不住地区CDN故障。用覆盖多地的监控网络能在客户之前发现区域问题。
内容检查结合状态码。200 OK是起点非终点。确认返回内容符合预期。
Dotcom-Monitor 的 Web应用监控 支持以上四点:基于比率的告警、端点分割、全球监测点及真实浏览器内容检测。API重度依赖的架构,API监控路径叠加模式校验和响应时间SLO,补强状态码检查。两者同用 告警流水线,无需三方信号拼接。
结语
最常见的 HTTP 状态码多年来未变:200、301、404、500、502、503——你这周都会遇到。变化的是团队从“看到代码”到“修复原因”的速度。
这差距正是优秀监控发挥价值之处。仅靠状态码只告诉你事件发生了。分层检查——状态、内容、真实浏览器、多区域——告诉你发生了什么、在哪里、及接下来该做什么。
如果想体验一下,Dotcom-Monitor 提供免费试用。指向你的任一端点,看看监控揭露了什么。