# 生产服务监控告警与无停机发布方案 ## 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 长期运行容器 后续评审通过后,长期运行容器建议使用: ```yaml 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--blue/green`,绿色槽使用基础宿主机端口加 `10000`;活动状态保存在 `/data/firstleg/deploy/blue-green-state/`。 - 候选 Web 槽先健康检查,再接入 `firstleg-production-routing` 网络;失败只删除候选, 不停止活动槽。 - 带 `@Scheduled` 或 MQ Consumer 的服务,Web 槽固定关闭后台任务;后台任务运行在不注册 Nacos、不暴露端口的单例 `*-worker` 容器。Worker 顺序切换,避免新旧任务双跑。 - 国内、海外 Gateway 分别在 `9000/19000`、`9300/19300` 之间切换,宿主机 Nginx `nginx -t` 成功后才 reload;失败恢复原配置。 - Admin、Client 分别在 `9001/19001`、`9002/19002` 之间切换,使用稳定的 `gateway-active`、`gateway-overseas-active` 路由别名。 - 所有 Java Web 槽使用优雅停机,默认最多等待 45 秒完成在途请求。 首次迁移顺序固定为: ```text 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 业务服务滚动发布 目标流程: ```text 旧实例继续接收请求 -> 启动新实例 -> 等待健康检查通过 -> 等待 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`。