Files
story/docs/server-health-monitoring.md
T

147 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 单机云端健康监测与告警手册
## 1. 目标与边界
`deploy/server/health-monitor.sh`为单机阿里云环境提供五分钟一次的轻量健康检查。它用于发现“部署模式与运行服务不一致、公网入口不可用、宿主机出现未授权公网监听端口、身份签发地址漂移、容器退出、备份过期或损坏、外部告警未配置、证书接近到期、定时任务停止、磁盘空间不足”等直接影响可用性或暴露面的事件。
该脚本不替代Prometheus、Grafana、云监控或真实值班系统。默认只写结构化状态文件和systemd日志;配置外部接收器后,状态发生变化时才发送一次HMAC签名Webhook,避免每五分钟重复通知。
## 2. 检查项
| 检查 | 正常条件 | 失败状态 |
|---|---|---|
| 部署模式 | `HOST_DEPLOYMENT_PROFILE`只能为`demo`或`production` | 非法值直接拒绝执行 |
| 应用运行环境 | API、Callbacks和Worker实际容器`APP_ENV`必须一致;`demo`要求`local`,`production`要求`prod` | `missing`、`mixed`或与部署模式不符的实际值 |
| 身份服务模式 | `demo`可使用开发模式;`production`不得使用Keycloak `start-dev` | `missing`或`development` |
| 外部告警接收器 | `demo`未配置时明确记录`not_configured`;`production`必须配置且HMAC密钥不少于32字节 | `not_configured`、`secret_missing`或`secret_invalid` |
| 公网地址 | `PUBLIC_ORIGIN`为HTTPS | `invalid_https_origin` |
| HTTPS入口 | `/api/v1/version`在10秒内返回成功 | `request_failed` |
| 公网监听端口 | 宿主机非回环TCP监听端口只能属于`22,80,443`;回环地址上的数据库或监控端口不计入公网暴露 | `unexpected_ports=...`、`probe_unavailable`或`invalid_probe_result` |
| OIDC | Discovery中的`issuer`与公网地址完全一致 | `issuer_mismatch`或`request_failed` |
| 容器 | PostgreSQL、Redis、MinIO、Keycloak、API、Callbacks、Worker、Web和Gateway均为运行态;有健康检查的容器必须为healthy | `missing`、容器状态或健康状态 |
| 模拟服务 | `demo`要求模拟语音和模拟告警服务都运行;`production`要求两者都不运行 | `incomplete_demo_stack`或`unexpected_running` |
| 备份 | 最新加密归档不超过36小时且外层SHA-256有效;`production`还要求异地备份启用并完成最新归档的回读验证 | `missing`、`age_seconds=...`、`checksum_failed`或异地备份状态错误 |
| 备份任务 | 最近一次`platform-backup.service`结果成功且退出码为0 | `result=.../exit=...` |
| 定时任务 | 备份和证书续期timer均为enabled/active | 当前启用/活动状态 |
| 证书 | 本地活动证书剩余时间不少于36小时 | `missing`或`remaining_seconds=...` |
| 磁盘 | 低于80%为健康,80%—89%为warning,90%及以上为critical | `used_percent=...` |
状态文件写入`/var/lib/data-terminal-cloud-monitor/status.json`,格式为`platform-server-health-v1`。每个检查只有稳定名称、状态和脱敏值,不包含数据库密码、Webhook地址、证书正文、业务数据或令牌。配置平台健康上报后,同一状态会每五分钟通过独立HMAC密钥发送到Callbacks并在运营联调诊断页面展示,详细协议见[云端主机健康状态接入开发说明](platform-health-reporting.md)。
## 3. 状态模型
```text
全部检查健康 → healthy,退出0
没有critical但存在warning → warning,退出0
任一检查critical → critical,退出1
```
systemd oneshot任务成功结束后显示`inactive (dead)`属于正常行为,应使用以下字段判断:
```bash
systemctl show platform-health-monitor.service -p Result -p ExecMainStatus -p ActiveState
```
期望结果为`Result=success`、`ExecMainStatus=0`。状态为critical时服务会显示失败,timer仍会在下一个周期继续执行。
## 4. 安装与运行
```bash
cd /opt/data-terminal-cloud/current
chmod 0755 deploy/server/health-monitor.sh deploy/server/install-monitoring.sh
deploy/server/install-monitoring.sh
systemctl start platform-health-monitor.service
systemctl list-timers platform-health-monitor.timer --no-pager
python3 -m json.tool /var/lib/data-terminal-cloud-monitor/status.json
```
定时任务在开机两分钟后首次执行,之后每五分钟执行并附加最多30秒随机延迟。`Persistent=true`确保错过计划时间后补跑。
## 5. 可选Webhook通知
安装脚本创建:
- `/etc/data-terminal-cloud/monitor.env`:`0600 root:root`;
- `/etc/data-terminal-cloud/monitor-webhook-secret`:独立随机HMAC密钥,`0600 root:root`。
编辑配置:
```bash
ALERT_WEBHOOK_URL=https://receiver.example.com/platform-health
ALERT_WEBHOOK_SECRET_FILE=/etc/data-terminal-cloud/monitor-webhook-secret
```
平台内部状态上报与外部告警分开配置;内部上报每个周期发送,外部告警仍只在综合状态变化时发送:
```dotenv
PLATFORM_HEALTH_REPORT_URL=https://121.41.46.238/callbacks/v1/platform-health
PLATFORM_HEALTH_REPORT_SECRET_FILE=/etc/data-terminal-cloud/platform-health-callback-secret
```
只有总体状态发生变化时才发送JSON状态文件。请求包含:
- `Content-Type: application/json`;
- `X-Platform-Timestamp`:Unix秒;
- `X-Platform-Signature: sha256=<hex>`;
- 签名正文:`HMAC-SHA256(secret, timestamp + "." + raw_body)`。
接收端应限制时间偏差、按时间戳和签名去重并使用恒定时间比较。Webhook地址和密钥不会进入状态文件或日志。正式配置前应先在接收端完成验签联通测试。
## 6. 参数
| 环境变量 | 默认值 | 说明 |
|---|---|---|
| `HOST_DEPLOYMENT_PROFILE` | `demo` | 主机部署模式;生产切换必须与异地备份、告警接收器和模拟服务退出同时完成 |
| `BACKUP_MAX_AGE_SECONDS` | `129600` | 最新备份最大年龄,36小时 |
| `CERTIFICATE_MIN_SECONDS` | `129600` | 证书最小剩余时间,36小时 |
| `DISK_WARNING_PERCENT` | `80` | 磁盘警告阈值 |
| `DISK_CRITICAL_PERCENT` | `90` | 磁盘严重阈值 |
| `EXPECTED_PUBLIC_TCP_PORTS` | `22,80,443` | 宿主机允许绑定非回环地址的TCP端口,逗号分隔 |
| `MONITOR_STATE_DIR` | `/var/lib/data-terminal-cloud-monitor` | 原子状态文件目录 |
| `MONITOR_CONFIG_FILE` | `/etc/data-terminal-cloud/monitor.env` | 可选通知配置 |
| `TLS_CERTIFICATE_FILE` | 根据`PUBLIC_ORIGIN`主机名推导 | 当前活动证书文件 |
阈值只能使用非负整数,磁盘警告阈值必须小于严重阈值。端口必须位于1—65535;修改允许端口前必须同步复核阿里云安全组,不能用扩大允许列表掩盖错误的数据库或缓存端口映射。普通调整无需重建镜像,但应记录变更理由并重新执行一次手工检查。
## 7. 验收与排障
正常路径:
```bash
/opt/data-terminal-cloud/current/deploy/server/health-monitor.sh
```
不改变线上状态的备份过期失败分支:
```bash
test_dir=$(mktemp -d /var/tmp/platform-monitor-test-XXXXXX)
MONITOR_STATE_DIR="$test_dir" MONITOR_CONFIG_FILE=/dev/null \
BACKUP_MAX_AGE_SECONDS=0 \
/opt/data-terminal-cloud/current/deploy/server/health-monitor.sh
```
期望退出1,状态为critical,唯一人工注入的严重检查为`backup_freshness`。测试目录验证后应精确删除。
监听策略解析器的正常、回环忽略和异常端口分支可独立验证:
```bash
python3 -B deploy/server/test_public_listener_policy.py
```
常用排障命令:
```bash
journalctl -u platform-health-monitor.service -n 100 --no-pager
systemctl list-timers platform-health-monitor.timer platform-backup.timer certbot-ip-renew.timer --no-pager
docker compose -f compose.yaml -f deploy/server/compose.override.yaml --env-file deploy/server/.env ps -a
```
生产分支可在不改变线上容器的情况下验证。临时配置`HOST_DEPLOYMENT_PROFILE=production`运行检查时,当前演示栈必须因`application_environment=local`、`identity_service_mode=development`、外部告警、异地备份及模拟服务同时进入critical;测试状态目录应与正式目录隔离。该检查读取容器实际环境和Keycloak启动命令,不能只改主机配置文件伪造生产结果。
## 8. 下一步生产化
1. 配置真实告警网关、主值班组和升级组,并完成HMAC验签联通测试。
2. 将状态接入云监控或Prometheus长期存储,建立可用率和告警送达趋势。
3. 启用现有OSS异地备份任务,确认上传、回读和SHA-256复算成功,并把最近验证时间纳入健康状态。
4. 使用外部OIDC、托管数据库/Redis/对象存储后,把资源级高可用、PITR和容量指标纳入同一状态模型。