一套代码按角色分机部署,共 7 台业务 ECS + 1 台运维机。公网入口走 ALB alb-sh7ntso1974zmdlz7u,C 端域名 api-id.beexofficial.com,后台 admin-api-id.beexofficial.com。
| 角色 | ECS 实例 | 内网 IP | 服务(systemd 单元 : 端口) |
|---|---|---|---|
| api ×2 | i-…3m34xy02 (a) / i-…7vptxiuis (c) | 172.27.107.15 / 172.27.87.12 | seahub-x-service : 7002(C 端 API) |
| edge ×2 | i-…993kia74 (a) / i-…1qi05xwm (c) | 172.27.107.16 / 172.27.87.11 | seahub-x-wa : 7010 · seahub-x-webhook : 7030 |
| worker ×2 | i-…ajkzw2s2 (a) / i-…kmez7t2t (c) | 172.27.107.17 / 172.27.87.10 | seahub-x-service : 7020(后台任务/结算) |
| admin ×1 | i-…kmez7t2u (c) | 172.27.87.9 | seahub-x-admin : 7003(管理后台) |
| ops ×1 | beex-id-ops-ai-01 | 172.27.87.23 | 运维机:cron 跑自愈看门狗,不承载业务流量 |
数据面:RDS MySQL(主库,库名 seahub_x_id_*)· Redis 主备 r-k1ad39c22bc37564(OTP/限流)。健康探测统一走各机 /actuator/health(DB/Redis 异常会返 503)。
seahub-x-service,而测试环境早已拆成 4 个独立服务),而且残留的旧 seahub-x-service.service 还在跟真正在用的 beex-api.service 抢占 7002 端口、两边密钥还不一致,导致鉴权 token 会间歇性验证失败。已把这个残留单元停用禁用。以后在测试环境操作前务必先按下表核对单元名,不要照抄生产的 systemctl restart seahub-x-service 一类命令。beex-id-test-service)| 角色 | systemd 单元 | jar 路径 | .env 路径 | 端口 |
|---|---|---|---|---|
| api | beex-api | /opt/beex-api/beex-api.jar | /opt/beex-api/.env | 7002 |
| wa | beex-wa-service | /opt/beex-wa-service/beex-wa-service.jar | /opt/beex-wa-service/.env | 7010 |
| webhook | beex-webhook | /opt/beex-webhook/beex-webhook.jar | /opt/beex-webhook/.env | 7030 |
| worker | beex-worker | /opt/beex-worker/beex-worker.jar | /opt/beex-worker/.env | 7020 |
| admin | seahub-x-admin-service | /opt/seahub-x-admin-service/seahub-x-admin-service.jar | /opt/seahub-x-admin-service/.env | 7003 |
为什么测试和生产不能做成完全一样的拓扑:生产是角色各占一台独立机器,同一个单元名 seahub-x-service 在不同机器上分别代表 api/worker(靠 SEAHUB_SERVICE_ROLE 区分);测试为省成本把 5 个角色压到一台机器,必须用不同单元名才能同时跑起来,这个差异是省钱带来的合理设计,不是需要"修掉"的错误——真正要改掉的是缺文档、缺告警导致踩坑,已经用这张表 + 下面的残留单元清理来解决。seahub-x-service.service 这个单元名以后只应该在生产出现,如果哪天在测试机上又看到它 active,大概率是有人按生产的肌肉记忆操作出来的,直接 systemctl disable --now seahub-x-service 即可。
ECS CPU/内存、RDS CPU/磁盘/连接、Redis CPU/内存。告警经管理后台中继(/api/v1/monitor/cloudmonitor-alarm)落库后转发飞书告警群。
运维机每分钟逐台拨测 9 个健康端口,异常/恢复/自愈动作全部直发飞书(加签,不经过应用,故业务全挂时也发得出)。见下节。
所有业务单元已配 Restart=always + RestartSec=5(drop-in autoheal.conf)。进程一崩,本机 systemd 5 秒内自动拉起,不依赖网络与任何外部组件。
脚本 .ai-workbench/self-heal.sh(ops 机 cron */1)。判定与动作:
| 探测结果 | 判定 | 自动动作 |
|---|---|---|
| 健康端口 200 | 正常 | 无(曾异常则发"已恢复") |
端口无响应,但 SSH:22 通 | 进程假死/卡住 | RunCommand 重启该服务 🔧 |
端口无响应,SSH:22 也不通 | 机器卡死 | ECS 强制重启该机器 ♻️ |
FAIL_THRESHOLD=3 次异常才动手。10min / 重启机器 30min 内不重复动作,防重启风暴。.ai-workbench/self-heal.OFF 时全程只告警不处置。10min 内不刷屏。参数都在 self-heal.sh 顶部常量(FAIL_THRESHOLD / SVC_COOLDOWN / REBOOT_COOLDOWN / ALERT_THROTTLE),改完下一分钟即生效。
touch /opt/beex-ai-workspace/x/.ai-workbench/self-heal.OFF # 关:只告警不动手 rm /opt/beex-ai-workspace/x/.ai-workbench/self-heal.OFF # 开:恢复自愈
# 生产(各角色独立机器) systemctl restart seahub-x-service # api/worker systemctl restart seahub-x-wa # edge wa systemctl restart seahub-x-webhook # edge webhook systemctl restart seahub-x-admin # 管理后台 # 测试(单机 5 服务,单元名不同,见①的拓扑表——别抄上面生产的命令) systemctl restart beex-api # api systemctl restart beex-wa-service # wa systemctl restart beex-webhook # webhook systemctl restart beex-worker # worker systemctl restart seahub-x-admin-service # 管理后台 # 机器(阿里云 ECS 控制台或 API RebootInstance --ForceStop true)
curl -s -o /dev/null -w '%{http_code}' http://<内网IP>:<端口>/actuator/health # 期望 200
| 消息前缀 | 含义 | 你要做什么 |
|---|---|---|
| 🔧 已自动重启服务 | 某服务假死,已自动重启 | 观察是否恢复;10min 内又报=看该服务日志 |
| ♻️ 已强制重启机器 | 某机器卡死,已自动重启 | 确认重启后恢复;反复=查 ECS 硬件/内存 |
| 🚨 已暂停(N/N 台同时异常) | 疑似 DB/Redis/网络等共享故障,已自动停止自愈 | 人工介入:查 RDS/Redis/ALB/VPC,别盲目重启业务机 |
| 🚨 已停用(开关关闭) | 自愈被人手动关了但服务异常 | 排障完成后 rm self-heal.OFF 恢复自愈 |
| ✅ 已恢复 | 该目标回到 200 | 无需动作 |
每个角色一条独立云效流水线,滚动发布 + 健康门禁 + 失败自动回滚。详见 部署总览。
| 环境 | api | wa | worker | webhook | admin |
|---|---|---|---|---|---|
| 生产 | 5109294 | 5109295 | 5109296 | 5109297 | 5109432 |
| 测试 | 5109562 | 5109563 | 5109564 | 5109565 | 5018487 |
.ai-workbench/deploy.sh。边缘机 wa/webhook 的环境变量在 /opt/seahub-x-service/{wa,webhook}.env(systemd EnvironmentFile),不是 /opt/seahub-x-*/.env——改 Redis/DB 连接时注意别改错文件。seahub/prod/),用傻瓜工具 .ai-workbench/secret 管理(list/get/set/apply/backup)。详见 密钥管理与恢复手册。self-heal.sh、pipeline.env 等运维文件内,不落本文档。