Files
docs/生产服务监控告警与无停机发布方案.md
2026-09-21 07:59:51 +08:00

14 KiB
Raw Permalink Blame History

生产服务监控告警与无停机发布方案

1. 文档状态与目标

  • 状态:待实施。
  • 当前动作:只记录方案,不修改生产环境、Jenkins、Compose 或告警配置。
  • 适用范围:国内生产、海外生产、Nacos、RocketMQ、Gateway、Admin、Client 及全部业务服务。

目标:

  1. 服务退出、失去健康状态或无法对外提供业务时能够及时通知。
  2. 服务具备合理的自动恢复能力,避免有限重试耗尽后永久停止。
  3. 正常发布期间减少无意义告警,但不掩盖部署失败和超时。
  4. 逐步从单实例短暂停服发布升级为可验证的滚动或蓝绿发布。

2. 当前问题与事故事实

2.1 已有能力

  • ECS 已配置 CPU、内存超过 80% 告警。
  • Jenkins 已具备部分生产部署成功、失败和取消通知。
  • 服务镜像包含 Docker 健康检查。
  • 单服务部署失败后具备自动回滚逻辑。

2.2 当前缺口

CPU、内存告警不能代表服务可用性。服务停止后 CPU 和内存使用率可能下降,因此不会触发资源阈值告警。

当前还缺少:

  • 容器退出告警。
  • 容器 unhealthy 告警。
  • 外部 HTTPS 可用性告警。
  • Nacos 实例数量下降告警。
  • RocketMQ NameServer、Broker 可用性及消息堆积告警。
  • 自动恢复耗尽告警。
  • 部署开始、回滚成功、回滚失败和部署超时通知。
  • 部署期间的精确维护窗口。

2.3 2026-09-18 File Service 发布失败

故障链路:

  1. RocketMQ NameServer 曾收到 SIGKILL,退出码为 137。
  2. Docker 未记录容器级 OOM,宿主机内核也没有 OOM 记录。
  3. NameServer 使用 restart: on-failure:3,三次重试耗尽后永久停止。
  4. Broker 容器仍在运行,但新启动的 File Service 无法通过 NameServer 获取 Topic 路由。
  5. File Service 新镜像启动失败,自动回滚到旧镜像后仍然失败。
  6. 手工恢复 NameServer 并确认 Broker 重新注册后,旧版 File Service 恢复健康。

本次故障证明:

  • “容器存在”不等于基础设施可用。
  • 自动重启不是告警系统。
  • 应用回滚不能解决外部依赖故障。
  • 关键基础设施必须独立监控,不能等业务服务重新部署时才发现。

3. 监控分层

监控应同时覆盖资源、容器、应用、入口和业务依赖。

层级 监控对象 典型告警
主机资源 CPU、内存、磁盘、inode、负载、网络 持续高使用率、磁盘将满、网络异常
Docker 容器状态、健康状态、重启次数 exited、unhealthy、频繁重启、容器缺失
应用 /actuator/health、JVM、连接池 健康检查失败、线程/连接池耗尽
外部入口 Admin、Client、国内/海外 Gateway HTTPS 不通、5xx、超时、证书异常
服务发现 Nacos 服务实例与健康实例数 核心服务无健康实例、实例数异常下降
消息系统 NameServer、Broker、Topic、Consumer Group 端口不通、Broker 未注册、消息堆积、死信增长
数据服务 RDS、Redis 连接失败、慢 SQL、连接数、容量、主从切换
发布系统 Jenkins 构建和部署阶段 发布失败、超时、回滚失败、版本不一致

任何单一层级都不能替代其他层级。

4. 告警规则建议

4.1 主机资源

当前 CPU、内存 80% 告警继续保留,并建议增加持续时间,避免瞬时峰值产生噪声。

指标 建议规则
CPU 超过 80% 持续 5 分钟告警;超过 95% 持续 2 分钟升级
内存 超过 80% 持续 5 分钟告警;可用内存持续过低升级
数据盘 使用率超过 80% 告警,超过 90% 升级
inode 使用率超过 80% 告警
Load 持续显著超过 CPU 核数告警
网络 连接失败、丢包或带宽长期打满告警

4.2 容器状态

关键容器包括:

  • Nacos。
  • RocketMQ NameServer、Broker。
  • 国内和海外 Gateway。
  • Auth、IAM、File、Event Bridge 等核心服务。
  • Admin、Client 前端容器。

告警规则:

  • 容器进入 exited:立即通知。
  • 容器进入 unhealthy:连续两次检测失败后通知。
  • 预期容器不存在:立即通知。
  • 10 分钟内重启超过 3 次:高优先级通知。
  • 告警恢复后必须发送恢复通知,包含中断时长。

4.3 外部可用性

至少从生产 ECS 之外检查:

  • https://admin.buggoglobal.com/
  • https://app.buggoglobal.com/
  • 国内 Gateway 轻量健康接口。
  • 海外 Gateway 轻量健康接口。

建议每 30 秒检查一次,连续失败 3 次后告警。检查内容包括:

  • DNS 解析。
  • TLS 证书与握手。
  • HTTP 状态码。
  • 响应时间。
  • 返回内容是否符合预期。

只在 ECS 内部探测不能发现公网 DNS、证书、反向代理或安全组问题。

4.4 RocketMQ

至少检查:

  • NameServer 9876 端口可连接。
  • Broker 能被 clusterList 查询到且为激活状态。
  • 关键 Topic 存在。
  • 关键 Consumer Group 存在。
  • 消息堆积量和最老消息年龄。
  • 死信队列增长。

不能只检查 Broker 容器运行状态。本次事故中 Broker 仍运行,但 NameServer 已停止。

4.5 Nacos

至少检查:

  • Nacos API/控制台可用。
  • 国内、海外命名空间可以认证读取。
  • 每个应运行服务存在健康实例。
  • 核心服务健康实例数变为 0 时立即告警。

5. 自动恢复策略

5.1 长期运行容器

后续评审通过后,长期运行容器建议使用:

restart: unless-stopped

适用于 Nacos、RocketMQ NameServer、RocketMQ Broker、Gateway 和业务服务。

该策略只负责恢复进程,不代表服务一定健康,也不能代替告警。

5.2 一次性任务

初始化和迁移任务不能使用无限重启,例如:

  • RocketMQ Topic 初始化。
  • 数据库迁移。
  • 一次性数据任务。

这些任务应在失败后停止并通知,避免无限重复执行有副作用的动作。

5.3 恢复边界

自动恢复不能执行:

  • 清空数据库或缓存。
  • 自动修改配置中心。
  • 自动执行 Flyway repair。
  • 自动忽略启动错误。
  • 跨服务随意重启全部容器。

6. Jenkins 发布通知

生产部署每次至少发送四类事件。

6.1 开始部署

通知内容:

  • 环境和区域。
  • 服务名称。
  • Git commit。
  • 镜像标签。
  • Jenkins 构建号和链接。
  • 操作来源。

6.2 部署成功

通知内容:

  • 新镜像版本。
  • 健康检查结果。
  • 部署耗时。
  • 是否发生容器重建。

6.3 部署失败

通知内容:

  • 失败阶段。
  • 首个有效错误摘要。
  • 新容器状态。
  • 是否已触发回滚。

6.4 回滚结果

必须区分:

  • 回滚成功:旧镜像恢复健康。
  • 回滚失败:旧镜像也未恢复,应升级为高优先级事故。

7. 部署期间的告警处理

7.1 不关闭全局监控

发布时不能关闭整台 ECS、整个区域或全部服务告警。只允许为正在部署的目标服务建立短时维护标记。

7.2 精确维护窗口

单实例发布阶段可采用:

  1. Jenkins 发布开始时写入目标服务维护标记,默认有效期 3~5 分钟。
  2. 维护期间普通短时健康失败不立即通知。
  3. 容器启动失败、回滚失败和维护超时仍立即通知。
  4. 发布成功后立即删除维护标记,不等待 TTL 自然过期。
  5. Jenkins 异常退出时,维护标记必须依靠 TTL 自动失效。

维护标记必须精确到环境、区域和服务,不得用“生产维护中”屏蔽全部告警。

7.3 仍需告警的情况

即使在维护窗口内,以下情况也不能静默:

  • Nacos、RocketMQ、RDS、Redis 等非目标基础设施故障。
  • Gateway 或公网入口整体不可用。
  • 部署超过预定时间。
  • 新旧镜像均不健康。
  • 自动回滚失败。

8. 当前单实例部署的限制

当前 Compose 使用相同服务名和容器名重建目标容器。发布过程中旧容器会停止,新容器完成启动和健康检查前可能存在短暂停服。

单实例模式下可以缩短中断,但无法真正保证无停机。仅延长告警等待时间也不能解决用户请求中断。

短期接受单实例时应:

  • 在低峰期发布。
  • 设置合理的健康检查启动宽限期。
  • 提前拉取镜像。
  • 保证配置、网络和依赖预检通过后再重建容器。
  • 将可接受中断时间形成明确指标。

9. 无停机发布目标

9.0 当前单机蓝绿实现

生产业务应用已采用逐服务蓝绿,不同时复制整套应用。数据库、Redis、Nacos 和 RocketMQ 不参与应用槽位切换,继续按各自高可用方案运行。

  • 后端槽位命名为 firstleg-production-<service>-blue/green,绿色槽使用基础宿主机端口加 10000;活动状态保存在 /data/firstleg/deploy/blue-green-state/。
  • 候选 Web 槽先健康检查,再接入 firstleg-production-routing 网络;失败只删除候选, 不停止活动槽。
  • 带 @Scheduled 或 MQ Consumer 的服务,Web 槽固定关闭后台任务;后台任务运行在不注册 Nacos、不暴露端口的单例 *-worker 容器。Worker 顺序切换,避免新旧任务双跑。
  • 宝塔反向代理永久指向固定入口 9000/9300/9001/9002,部署脚本不得修改宝塔管理的 站点 vhost 文件。独立的 00-blue-green-*.conf 在固定入口后执行槽位切换。
  • 国内、海外 Gateway 槽位分别使用 19000/29000、19300/29300,宿主机 Nginx nginx -t 成功后才 reload;失败恢复切流层配置。
  • Admin、Client 槽位分别使用 19001/29001、19002/29002,使用稳定的 gateway-active、gateway-overseas-active 路由别名。
  • 所有 Java Web 槽使用优雅停机,默认最多等待 45 秒完成在途请求。

首次迁移顺序固定为:

Admin -> Client
  -> gateway -> gateway-overseas
  -> auth -> iam -> order -> warehouse -> firstleg -> finance -> file -> print -> integration
  -> audit -> event-bridge(CN/OVERSEAS) -> lastleg -> warehouse-overseas

Gateway 切换前会检查两个前端是否已经使用稳定别名;不满足时发布失败并保留旧 Gateway。 后续发布只双开当前目标服务,不要求整套业务同时占用双倍内存。

9.1 业务服务滚动发布

目标流程:

旧实例继续接收请求
  -> 启动新实例
  -> 等待健康检查通过
  -> 等待 Nacos 注册为健康实例
  -> 将流量逐步交给新实例
  -> 旧实例停止接收新请求
  -> 等待在途请求完成
  -> 停止旧实例

要求:

  • 同一服务至少两个实例。
  • 容器名称不能固定为唯一名称。
  • 实例不能争用相同宿主机端口。
  • 定时任务、消费者和 Worker 必须评估多实例行为。
  • 应用必须支持优雅停机。
  • 数据库变更必须遵守 Expand/Contract,详见数据库版本迁移方案。

9.2 Gateway 发布

Gateway 自身不能只依靠 Nacos。至少部署两个实例,并由 Nginx、ALB 或等价负载均衡器负责:

  • 健康检查。
  • 逐个摘除旧实例。
  • 新实例验证后再接流量。
  • 发布失败时继续使用旧实例。

9.3 Admin 与 Client

前端可采用蓝绿目录或蓝绿容器:

  1. 新版本部署到非当前槽位。
  2. 检查静态资源和首页。
  3. 原子切换 Nginx upstream 或软链接。
  4. 保留旧版本用于快速切回。

9.4 单 ECS 的边界

同一 ECS 上双实例可以解决发布中断和单容器故障,但不能防止:

  • ECS 宕机。
  • 数据盘故障。
  • Docker daemon 故障。
  • 整机网络故障。

真正的主机级高可用需要至少两台 ECS,并由负载均衡器进行健康检查和流量切换。

10. 告警等级与通知渠道

等级 示例 通知建议
P1 国内/海外入口不可用、数据库不可用、回滚失败 企业微信 + 电话/短信,立即处理
P2 核心服务无实例、NameServer/Broker 故障、持续高错误率 企业微信告警群,限时处理
P3 CPU/内存 80%、磁盘趋势、单次容器重启 企业微信运维群,工作时段跟进

所有告警应包含:

  • 环境、区域、主机和服务。
  • 开始时间和持续时间。
  • 当前状态与最近变化。
  • 可点击的日志或监控入口。
  • 推荐的第一条只读诊断命令。
  • 恢复通知。

通知不得包含密码、Token 或完整敏感连接串。

11. 分阶段实施建议

阶段 A:补齐发现能力

  • 保留现有 CPU、内存 80% 告警。
  • 增加磁盘、inode 和主机可用性告警。
  • 增加关键容器退出、unhealthy、缺失及频繁重启告警。
  • 增加 Admin、Client、国内/海外 Gateway 外部 HTTPS 探测。
  • 增加 Nacos 健康实例和 RocketMQ NameServer/Broker 检查。

阶段 B:改进恢复与发布通知

  • 评审并调整长期运行容器重启策略。
  • Jenkins 增加开始、成功、失败和回滚结果通知。
  • 增加目标服务级维护标记和超时保护。
  • 发布前增加基础设施依赖预检。

阶段 C:降低发布中断

  • 业务服务支持双实例。
  • Nacos 下线与优雅停机接入发布脚本。
  • Gateway 和前端采用蓝绿或滚动方式。
  • 验证消费者、定时任务和文件服务的多实例安全。

阶段 D:主机级高可用

  • 增加第二台生产 ECS。
  • Gateway 接入 ALB 或等价负载均衡。
  • 关键实例跨主机分布。
  • 定期执行单实例故障和滚动发布演练。

12. 后续实施验收标准

  • 手工停止任一关键容器后,规定时间内收到告警。
  • 容器恢复后收到恢复通知并记录中断时长。
  • NameServer 停止时能够在 File Service 发布前发现。
  • 正常单服务部署不会触发无意义的普通可用性告警。
  • 部署超时或回滚失败即使处于维护窗口也会告警。
  • 告警明确区分应用失败、基础设施失败和资源压力。
  • 重复告警受到抑制,但事故状态持续可见。
  • 双实例发布阶段实际请求无明显中断。
  • 监控系统故障本身也有独立告警。

13. 与其他文档的关系

  • 数据库发布顺序和 Expand/Contract:数据库版本迁移与Jenkins自动发布方案.md。
  • 阿里云资源、高可用、压测和整体上线:阿里云生产环境选型压测与上线手册.md。
  • 测试环境持续部署:测试环境Jenkins部署指南.md。