
系统平时正常一到集中操作时就提示503 Service Unavailable过一会儿又恢复。也有系统是在发布新版本时短暂出现503。两者都表示当前服务无法处理请求但触发机制可能完全不同。503需要先确定谁在拒绝请求维护规则、限流网关、没有可用后端的负载均衡还是主动报告不可用的应用。内存高、连接池满、容器unhealthy都是线索不会在所有架构里自动转换为503。本文使用Nginx、Spring Boot与容器健康检查举例先建立排查顺序再完整拆解“公司多人访问触发503”和“发布期间暂时不可用”两种场景。配置片段需合并到既有工程案例与日志为教学示例不代表线上事故实测。目录503与500、502、504有什么不同限流也可能返回503进程存活与可以接单不是同一回事资源问题需要看时间序列维护窗口要让客户端知道如何应对先确定恢复后的检查范围案例拆解为什么公司里多人打开页面就503另一个分支发布时503为什么不能只看容器绿色给AI的排查输入应包含什么一、503与500、502、504有什么不同状态表达的含义不能直接推断500服务端遇到意外条件必然是代码语法错误502网关取得无效上游响应必然需要重启503当前无法处理服务请求必然是CPU不足504网关等待上游超时操作一定未完成图1限流、维护、无可用实例和应用故障都可能表现为503应先找到实际拒绝请求的节点。如果是维护页面检查维护开关如果只有突发请求被拒绝查限流日志如果滚动更新时出现检查可用实例与流量切换。不要在没有证据时同时扩容、放宽限流和关闭健康检查。二、限流也可能返回503Nginxlimit_req默认拒绝状态为503也可配置为429。因此503并不一定说明后台进程已经不可用。下面展示限流规则的配置层级阈值仅作示例需要按业务容量测试# http上下文 limit_req_zone $binary_remote_addr zoneapi_rate:10m rate5r/s; # 放入已有server内的目标location location /api/ { limit_req zoneapi_rate burst10 nodelay; limit_req_status 429; proxy_pass http://127.0.0.1:8080; }图2规则拒绝与实际服务故障需要不同处理改变状态码或放宽限流不等于解决容量问题。主动限流时使用429可以让客户端更容易区分“请求太多”和“服务暂时不可用”。但不能仅改状态码就算解决共享出口的多个用户可能共用IP需要检查按IP限流是否符合业务。反向代理后的真实地址解析也必须只信任可信上游。三、进程存活与可以接单不是同一回事存活检查关注进程是否还应继续运行就绪检查关注是否适合接收流量。启动尚未结束、关键初始化未完成时进程可以存活但暂不就绪。图3存活、就绪和流量分配是不同环节健康状态只有被网关或编排机制使用才会影响流量切换。Spring Boot Actuator可以配置健康分组。并不是所有项目默认都有/actuator/health/readiness需核对依赖、版本和端点开放方式。管理端点应在受控范围内使用不公开详细依赖信息。Docker Compose里的healthcheck会记录容器健康状态但仅标记unhealthy通常不会自动重启容器也不会让普通Nginx主动摘除它。要核对是否有编排器、负载均衡或其他组件真正消费健康结果。共享数据库的短暂抖动若导致所有实例同时不就绪可能放大故障。哪些依赖影响就绪要根据业务是否能降级决定不能把所有外部服务都塞进存活检查。四、资源问题需要看时间序列free-mdf-hdf-isudojournalctl-k--since30 minutes ago--no-pagerdockerstats --no-stream这些读操作帮助检查内存、磁盘空间、inode、内核终止记录和容器资源。系统没有使用Docker时略过最后一项。日志与指标要对应503发生的时间事后单次CPU截图不能说明峰值期间发生了什么。图4把负载增加、资源等待和服务拒绝放在同一时间线上结合日志确认瓶颈是否真正相关。连接池耗尽还需看等待数、借用时长和数据库慢操作。单纯调大连接池可能把压力转移给数据库先查连接是否释放、事务是否过长、请求是否无限排队。五、维护窗口要让客户端知道如何应对计划维护可以返回503并按实际情况提供Retry-After。恢复时间不确定时不要承诺不真实的倒计时。客户端重试应有限次、带退避并对写操作核对业务幂等性。例如“查询稍后再试”和“审批提交稍后再试”不能采用同一种无限重试策略。后者应先确认服务器有没有处理成功再决定是否重发。六、先确定恢复后的检查范围图5服务恢复后继续验证容量、健康策略和客户端重试防止恢复过程再次引发过载。检查项验证内容错误来源已确定网关或应用的拒绝规则实例状态有实际接收流量的就绪实例容量持续观察资源和排队情况限流正常使用通过超限符合设计重试无无限循环或重复业务写入下面把这份检查表应用到两个不同场景一个请求被挡在入口另一个需要核对服务就绪与发布流程。七、案例拆解为什么公司里多人打开页面就503假设一个教学环境出现以下现象一个人打开工作台正常多位同事同时访问时部分接口503手机切换到移动网络后又正常。重启后台没有改变现象。这组条件首先提示“请求来源与入口规则”值得排查而不是已经证明服务器资源不足。公司用户可能共享公网出口也可能是代理错误地把所有用户识别为同一个来源。1. 在入口记录限流判定下面片段适用于支持$limit_req_status的Nginx版本该变量自1.17.6提供。格式放在http上下文access_log放在实际处理API的server或location中log_format availability $time_iso8601 rid$request_id method$request_method uri$uri status$status limit$limit_req_status upstream$upstream_status addr$upstream_addr rt$request_time; # 在目标server或location内引用 access_log /var/log/nginx/availability.log availability;日志里不写认证头和请求体即使只记录路径也应注意路径可能带业务标识。应用需要另外接入请求ID才能关联到后台日志。以下为用于解释字段的示意记录并非实际采样riddemo-a methodGET uri/api/dashboard status200 limitPASSED upstream200 riddemo-b methodGET uri/api/dashboard status503 limitREJECTED upstream-第二行说明这次请求被限流规则拒绝没有取得上游状态。再结合error log中的limiting requests记录可以把排查方向收敛到入口策略。但只有upstream-还不够本地return、静态响应等也可能没有上游状态。必须结合limit字段和生效配置不能把缺少上游状态直接当成限流证明。2. 核对的是生效规则不只是某个配置文件sudonginx-tsudonginx-T-T会输出完整生效配置可能含内部域名、证书路径及其他敏感配置只在受控终端查看不把原样输出粘贴到公开文章。核对以下问题限流键是否为$binary_remote_addr多个用户是否确实共用出口。Nginx前方是否还有代理真实IP解析是否仅信任指定代理。页面是否一次并发发出大量接口请求而不是用户手动频繁操作。多个接口是否共用同一个zone从而共同消耗额度。子级location是否重新声明规则改变了上级继承关系。burst不是“增加每秒额度”nodelay也不表示不再限流。前者用于容纳突发超额请求后者影响突发请求是否等待持续速率仍受规则约束。3. 修复方向与回退条件如果正常业务被共享IP规则误伤可以评估更合理的入口限流与应用账号配额分工。账号身份应来自服务端验证不能直接信任浏览器任意传入的userId请求头否则规则容易被绕开。如果是工作台一次加载二十多个接口减少重复请求、合并合理查询、限制前端并发也可能比直接放大阈值有效。调整应先在测试环境用正常业务节奏验证。支持的版本可用limit_req_dry_run观察候选规则命中情况但它不会真正限制请求因此只能放在受控测试或已有其他保护的观察窗口不能在承压生产环境随手关闭保护。变更前保存配置与阈值变更后确认证据判断正常工作台访问不再被误拒绝正向场景通过受控超限请求仍按规则拒绝防护没有失效后台延迟和排队没有明显恶化没把压力全部转移到应用错误请求不发生自动重试风暴客户端行为正确如果放宽后排队和延迟持续上升应恢复已记录的安全阈值并定位容量瓶颈而不是继续扩大burst。八、另一个分支发布时503为什么不能只看容器绿色当日志显示请求已经到达应用并由其返回503限流案例的结论就不适用。可从受控管理网络检查实际启用的健康端点。以下为启用探针的Spring Boot配置片段工程需有Actuator依赖management:endpoint:health:probes:enabled:trueshow-details:neverendpoints:web:exposure:include:health这不等于已经配置好访问控制仍要按项目安全配置限制管理入口。端点是否开放、路径和端口是否独立都要核实。探针成功也不自动证明业务数据库读写正常。# 仅在实际开放此端点的受控环境使用curl-i--max-time3http://127.0.0.1:8080/actuator/health/readiness# 容器名按环境替换输出只保留状态避免导出完整配置dockerinspect--format{{json .State.Health}}backend容器健康状态只是一份观察结果。真正的发布流程还需要新实例启动、就绪、接流量、旧实例停止接单并排空已有请求。单实例停止再启动通常存在不可用窗口不能把它描述成无损滚动发布。因此这类503的验收还应包含“发布过程中有没有可用实例”“就绪失败是否被正确摘除”“恢复后是否重新接流量”而不只是服务最后启动成功。九、给AI的排查输入应包含什么提供脱敏后的失败时间、响应来源、limit状态、上游状态、健康变化和最近配置差异要求AI先区分已确认事实与待验证假设。不要只给一句“503请帮我扩容”。规则误伤与真实过载需要相反的处理方向证据不足时扩容、关闭限流和重启都可能只是碰运气。参考资料Nginx请求限流模块与默认状态Spring Boot健康检查Docker Compose服务配置