503 是什么
503 Service Unavailable 表示服务器暂时无法处理请求,原因通常是过载或正在维护。RFC 9110 §15.6.4 建议这种响应带上重试等待时间头,告诉客户端什么时候可以再来。它与相邻错误码的分工很清晰:503 是服务自己说「我现在不接客」,502 是网关代理的上游坏了,504 是上游响应太慢。过载时主动返回 503 是一种保护手段,能让系统在压力下保住已有请求,而不是全部拖垮。
基本信息
| 名称 | 503 Service Unavailable(RFC 9110 §15.6.4) |
|---|---|
| 作用 | 临时不可用:过载、维护或依赖故障 |
| 关键头部 | 重试等待时间头,告知客户端何时再来 |
| 与 502 区别 | 503 是自身暂时不服务,502 是上游不可用 |
| 配套 | 容量指标、限流器、维护开关 |
典型使用场景
- 发布维护窗口:主动返回 503 并展示维护页,避免用户看到残缺功能
- 过载保护:连接数或队列超过阈值时拒绝新请求,保住已完成的工作
- 依赖降级:关键下游不可用时,非核心功能整体降级并给出明确提示
- 容量收缩:弹性缩容过程中先摘流量再下线实例
- 灰度回滚:回滚期间短暂拒绝新请求,避免新旧逻辑交叉处理同一批数据
维护页配置示例
维护页配置示例
server {
# 存在维护标记文件时整体返回 503,便于运维一键切换
if (-f /etc/nginx/maintenance.flag) {
return 503;
}
error_page 503 /maintenance.html;
location = /maintenance.html { root /usr/share/nginx/html; } # 维护页放本地,不依赖后端
}三个相邻错误码对比
| 错误码 | 责任方 | 处置动作 |
|---|---|---|
| 502 | 网关到上游的连接 | 拉起后端,核对端口与协议 |
| 503 | 服务自身过载或维护 | 扩容、限流、放出维护页 |
| 504 | 上游处理过慢 | 优化慢点,长任务改异步 |
| 500 | 应用内部异常 | 修代码,检查依赖与配置 |
过载保护的落地要点
- 限流要比彻底崩溃温和:宁可拒绝一小部分请求,也不要让全部请求都超时
- 重试等待时间要真实可信,随口给一个很小的值只会招来更密集的重试
- 队列要设上限,无上限的排队只会把延迟无限拉长,用户等待却没有结果
- 非核心功能先降级,把资源留给支付、登录这类关键路径
- 监控要区分「主动拒绝」与「被动崩溃」,两者的处置动作完全不同
重试等待时间是 503 最有价值的部分:客户端与中间层照着它退避,能把尖峰摊平。缺少这个头,所有调用方只能盲猜节奏,很容易在恢复瞬间再次把服务打满。
把维护页配成成功状态码,监控与拨测都感知不到服务中断,用户在页面上看到提示但你的可用率曲线依然漂亮,故障会被拖到更久才被发现。
恢复期要做的事
- 先确认容量真的回来了再摘掉维护开关,过早放量会让系统立刻二次过载
- 分阶段放量并盯住核心指标,比一次性全量恢复安全得多
- 把本次的触发阈值与真实承载能力记录下来,作为下一次容量评估的依据
- 复盘要区分主动拒绝与被动崩溃,只有后者才是真正需要修掉的可用性缺陷
触发来源与观察指标
| 触发来源 | 观察指标 |
|---|---|
| 容量过载 | 队列长度、连接数、平均与长尾延迟 |
| 维护开关 | 开关状态、维护页访问量 |
| 依赖降级 | 被降级功能的拒绝计数与下游错误率 |
如何让中断更平滑
- 维护窗口提前公告并让页面带出恢复时间,用户不会反复刷新试探
- 能用滚动发布就别做整体维护,把中断窗口压到最小
- 维护页要独立于后端放在网关本地,否则后端不可用时维护页也打不开
- 用自动化开关替代人工改配置,减少误操作带来的长时间不可用