服务健康检查
多服务器运行后,偶尔有服务挂掉。
问题:
- 某个应用服务器进程崩溃
- 某个数据库连接池耗尽
- 某个 Redis 实例内存溢出
- 人工发现和恢复太慢
1. 健康检查端点
服务挂掉要能被自动发现,第一步是给每个实例一个能说清自身状态的健康检查端点。这个端点不能只回一句「活着」——进程还在但数据库连接池已经耗尽、依赖全面超时,对上游来说同样是不可用。检查项要分存活和就绪两档,负载均衡据此决定还要不要把流量转给它。
1. 健康检查端点
- 步骤 1:设计健康检查端点的返回内容:状态码、检查项结果和失败原因
- 步骤 2:区分存活检查与就绪检查,覆盖进程存活和关键依赖可用性
- 步骤 3:为检查项设置超时与超时阈值,避免检查本身拖垮实例
- 步骤 4:让上游按检查结果刷新路由,把不健康实例从转发列表摘除
关注点:存活与就绪的区分、依赖检查项和摘除流量的准确率。
2. 自动重启脚本
有了健康检查,还要有人去执行恢复。重启脚本应该由外部监控在确认实例持续不健康后触发,而不是让实例自己拉自己——自己挂掉的时候是喊不出人的。脚本要做到幂等:重复触发只会多重启一次,不会叠出多个进程;同时要记录重启原因和次数,避免无限重启把真正的故障掩盖过去。
2. 自动重启脚本
- 步骤 1:设定触发重启的条件:连续多次健康检查失败并超过观察窗口
- 步骤 2:由外部监控触发重启脚本,脚本先确认目标进程确实处于异常状态
- 步骤 3:把脚本设计成幂等执行,重复触发不会产生多个进程或重复清理
- 步骤 4:记录重启原因、次数和结果,超过次数上限时转人工处理而不是继续重启
关注点:重启触发条件、脚本幂等性与重启风暴的防范。
3. Systemd 服务配置
脚本重启只是兜底,真正该做的是让 systemd 主动把服务拉起来并守住它。unit 文件里要写清楚服务的启动命令、工作目录、运行用户和依赖顺序,还要配置 Restart 策略与重启间隔,让进程退出后由 systemd 负责拉起。这一节先把运行配置定下来,后面的进程管理再在此基础上补充更细的控制。
3. Systemd 服务配置:运行配置
- 步骤 1:编写 unit 文件,指定启动命令、工作目录、运行用户和重启策略
- 步骤 2:配置 Restart 与重启间隔,并设置启动超时和依赖顺序
- 步骤 3:用 systemd-analyze 校验配置语法,再执行重启验证服务能被正确拉起并托管
关注点:unit 关键指令、Restart 策略与启动依赖顺序。
4. 进程管理
systemd 把进程带起来之后,还要管住它:不要启动出重复实例,崩溃了要留下现场,内存涨上去要能收回来。常见的做法是用 Type=forking 配合 PIDFile 锁定唯一进程,启动前检查旧进程是否还在,异常退出时用 core dump 保留堆栈,内存超限则由 watchdog 触发重启。这些细节决定系统是否可控。
4. 进程管理
- 步骤 1:用 PIDFile 锁定唯一实例,启动前校验旧进程是否已经退出
- 步骤 2:配置异常退出时生成 core dump,并为服务设置内存与任务数上限,超限由 watchdog 回收
- 步骤 3:通过 systemctl 查看进程树与资源占用,确认进程管理符合预期
关注点:唯一进程保证、崩溃现场留存与内存水位控制。
自愈机制建好之后,监控告警的职责就从「通知故障」变成「发现自愈失效」。进程崩溃被 systemd 拉起,接口不再返回错误,但用户可能已经经历了一次请求失败。因此除了存活和延迟,还要盯重启频率、熔断次数和健康检查失败率——这些数字悄悄上涨,才是真正需要人介入的信号。
监控告警
- 步骤 1:采集实例存活、接口错误率、响应延迟和健康检查失败次数
- 步骤 2:监控自动重启次数与频率,异常上涨说明问题没被真正修复
- 步骤 3:为连续重启、错误率越线和依赖超时分别配置分级告警
- 步骤 4:把告警接到值班通道并验证可达,确认异常能在用户投诉前被发现
关注点:重启频率、失败率趋势与自愈失效的早期信号。
发现内容有问题?
告诉我们哪里需要改进。
