503 Service Unavailable 是什么原因
503 和 502 经常被混着说,其实差别很大。
502 是网关说「我联系不上后面」;503 是服务本身说「我知道你来了,但我现在处理不了」。一个指向连接,一个指向容量。
三种 503
容量打满。 php-fpm 的 max_children 用完了,线程池满了,数据库连接数到顶了。新请求排队排到超时,直接返回 503。
主动限流或维护。 有些程序在维护模式返回 503;有些 WAF 和 CDN 在触发限流时也返回 503,还会带一个 Retry-After 头。
CDN 自造。 源站连不上或者回源失败,部分 CDN 会直接给用户 503,而不是透传源站的错误。
靠分布判断
一直 503,跟并发无关:服务没起来,或者停在维护模式,去看进程和配置。
平时正常,一有活动就 503:容量问题,看进程数和队列。
只有某些节点 503:那一层在限流,或者那个 CDN 节点回源有问题。
看几个具体数字
php-fpm 开了 status 页面的话,看 listen queue(排队数)、active processes、max children reached(这个不为 0 就说明撞过上限)。
数据库看当前连接数和 max_connections 的比例。到 80% 就该处理了,别等打满。
处理分两层
短期止血:适当调大 pm.max_children、开页面缓存、对非核心接口限流降级。这些能撑过一波流量。
长期:把同步的重活改成队列异步,热点数据前置缓存,单机扛不住就拆。加机器是最后一步,不是第一步——代码里一个慢查询,加十台机器也只是晚十分钟崩。
一个容易忽略的点
调大 max_children 要考虑内存。每个 PHP 进程按 50-80MB 算,32 个就是 2GB 上下,机器内存不够反而会 OOM,表现从 503 变成 502。
改之前先 free -m 看一眼余量。
复测的时候用 网站测速 同时跑几个节点,能看出是全局容量问题还是某个节点的问题。