Healthchecks v4.4 进阶实战与运维
Healthchecks v4.4 运维实战:后台进程体系、入站邮件 ping、周报推送、Prometheus 指标、备份恢复、数据清理、升级迁移与故障排查,全部命令带真实回显。
Healthchecks v4.4 进阶实战与运维
目标:面向已部署的 Healthchecks v4.4,讲透后台进程体系与日常运维闭环——告警派发与周报推送的进程化托管、入站邮件 ping、Prometheus 指标接入、备份恢复演练、数据清理、版本升级迁移,以及真实故障排查记录。已在 Ubuntu 22.04 源码部署环境实测通过,Docker 部署差异单独标注。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Healthchecks:v4.4(源码部署
/opt/healthchecks,venv/opt/venv,运行用户hc) - 数据库:PostgreSQL 16.15(PGDG 仓库,集群端口 5433,库
hc/用户hc/密码q1w2e3r4) - systemd 服务:
healthchecks-web、healthchecks-sendalerts;环境文件/etc/healthchecks - 管理账号:
admin@example.org;演示 Check:backup-db(UUID83459720-9231-40d0-b7c6-5d237327951d) - API Key:
hcw_WEvuuwb0tRz3jxAhM3BfYkT2bGAi - 官方镜像部署补充验证:
healthchecks/healthchecks:v4.4+postgres:16(Compose v5.5.1)
二、软件概览:后台进程体系
Healthchecks 是典型的「Web + 异步任务」双轨架构,自托管运维的核心就是把这几类进程管明白:
| 进程/命令 | 职责 | 部署形态与托管方式 |
|---|---|---|
| web(gunicorn/uwsgi) | Web 界面、API、接收 ping | 源码:systemd healthchecks-web;镜像:内置 uwsgi |
manage.py sendalerts | 每 2 秒扫描到期 Check,状态翻转时发告警 | 常驻进程;源码:systemd 常驻;镜像:内置自动运行 |
manage.py sendreports | 周报/月报/提醒邮件 | 常驻进程(同上,镜像内置) |
manage.py smtpd | 入站邮件 ping 的 SMTP 服务器 | 可选;镜像用 SMTPD_PORT 启用 |
manage.py pruneobjects | 清理 S3 上过期的 ping body | 批处理;配置了 S3 才有意义 |
manage.py prunetokenbucket | 清理过期的令牌桶(限流)记录 | 批处理;建议每周 cron |
manage.py settelegramwebhook | Telegram 渠道回调注册 | 一次性 |
💡 技术拓展:为什么 sendalerts 必须常驻而不能用 cron 每分钟跑一次?早期版本(v3.x 及以前)sendalerts 支持单次运行模式,社区文档普遍建议 crontab 每分钟调用;v4.4 的实现里循环写在
handle()内部(while not self.shutdown: ... sleep(2)),启动即常驻、靠信号优雅退出。用 cron 调常驻进程会每分钟叠一个进程,务必以 systemd 服务或镜像内置编排为准。
三、实战示例
3.1 告警派发的进程化托管与验证
healthchecks-sendalerts.service 单元(与 web 同构,EnvironmentFile 共享邮件配置):
[Unit]
Description=Healthchecks alert dispatcher (sendalerts)
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=simple
User=hc
Group=hc
EnvironmentFile=/etc/healthchecks
WorkingDirectory=/opt/healthchecks
ExecStart=/opt/venv/bin/python manage.py sendalerts
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
启用并确认:
systemctl enable --now healthchecks-sendalerts
systemctl is-active healthchecks-sendalerts
Created symlink /etc/systemd/system/multi-user.target.wants/healthchecks-sendalerts.service → /etc/systemd/system/healthchecks-sendalerts.service.
active
端到端验证方法(实测记录):把演示 Check backup-db 用 API 改成 60 秒周期 + 60 秒宽限并停止 ping,约 2 分钟后状态转 down,告警邮件随即发出。邮件侧用 aiosmtpd 调试服务器抓包(python -m aiosmtpd -n -l 127.0.0.1:2525,/etc/healthchecks 的 EMAIL_HOST=127.0.0.1/EMAIL_PORT=2525 指向它),真实抓到的两封邮件主题:
Subject: UP | backup-db
Subject: DOWN | backup-db
DOWN 邮件正文(节选)说明了判定原因与现状摘要:
The check "backup-db" has gone down.
Reason: success signal did not arrive on time, grace time passed.
Total pings: 8 (since Oct 16, 2026)
Status changed to down at: Fri, 16 Oct 2026 15:42:22 +0000
验证后把 Check 周期改回正式值(POST /api/v3/checks/<uuid> 传回 schedule/grace)。
3.2 入站邮件 ping(Email-to-Ping)
适用场景:任务所在机器没有出站 HTTP 但能发邮件,或想留一份「任务输出全文」在 ping 记录里。三步启用:
第一步:配置收件域名(PING_EMAIL_DOMAIN)并在 /etc/healthchecks 补充后重启服务(源码部署直接手动起 smtpd):
cd /opt/healthchecks
set -a && . /etc/healthchecks && set +a
(nohup su hc -s /bin/bash -c "cd /opt/healthchecks && exec /opt/venv/bin/python manage.py smtpd --port 2526" > /tmp/hcsmtpd.log 2>&1 &)
实测输出:
Starting SMTP listener on 0.0.0.0:2526 ...
第二步:向 Check 的入站地址发邮件。地址格式 <check-uuid>@<PING_EMAIL_DOMAIN>(Check 详情页可复制)。实测用 Python smtplib 发送:
# /tmp/mailping.py
import smtplib
from email.message import EmailMessage
m = EmailMessage()
m["From"] = "cron@db-server.internal"
m["To"] = "83459720-9231-40d0-b7c6-5d237327951d@localhost"
m["Subject"] = "backup-db report"
m.set_content("backup finished OK, size=1.2G")
with smtplib.SMTP("127.0.0.1", 2526) as s:
s.send_message(m)
print("mail sent")
python3 /tmp/mailping.py
mail sent
第三步:确认 ping 已落库(n_pings +1,且 Check 由 down 转 up):
n_pings: 11 status: up
⚠️ 注意两点:①
manage.py smtpd是入站专用服务器,只接受 Check 地址(<uuid>@域名),发给admin@example.org这类普通地址会拒收550 5.1.1 Recipient rejected——所以它不能当出站邮件的测试端;② 入站邮件的正文会存进 ping 记录(受 PING_BODY_LIMIT 约束),配合 Check 的「subject/body 关键字过滤」可以实现「邮件里含 FAIL 才算失败」的语义。
镜像部署启用方式:.env 加 SMTPD_PORT=2526 并在 compose 里为 web 服务映射该端口,容器启动时自动拉起 smtpd,无需手动运行。
3.3 周报/月报推送(sendreports)
用户级开关在「Profile → Reports」(off/weekly/monthly),配合 next_report_date 到期发送。实测强制触发一次周报:
第一步:把账号设为周报且将下次发送时间拨到过去:
# /tmp/rep.py
from hc.accounts.models import Profile
from django.utils.timezone import now
from datetime import timedelta as td
p = Profile.objects.get(user__email="admin@example.org")
p.reports = "weekly"
p.next_report_date = now() - td(minutes=1)
p.save()
print("reports:", p.reports, "next_report_date:", p.next_report_date)
cd /opt/healthchecks
/opt/venv/bin/python manage.py shell < /tmp/rep.py
reports: weekly next_report_date: 2026-10-16 15:44:41.461047+00:00
第二步:运行 sendreports(v4.4 中它同样是常驻进程,不传 --loop 时处理完到期项即退出,适合演练与 cron 每小时兜底):
set -a && . /etc/healthchecks && set +a
/opt/venv/bin/python manage.py sendreports
实测输出:
sendreports is now running
Done.
第三步:在 aiosmtpd 抓包端确认周报邮件发出:
Subject: Weekly Report
💡 说明:周报内容含项目内 Check 的在线率/掉线摘要,是低频运维(如领导周会)的好抓手。若
Done.但没发信,多半是next_report_date已在处理中被推进(乐观锁设计,防止重复发送),重新把时间拨过去即可;真正没配置 SMTP 时报AssertionError: No SMTP configuration,先补环境变量(记得set -a; . /etc/healthchecks; set +a)。
3.4 Prometheus 指标接入
配置 METRICS_KEY(默认未启用)后开放 /api/v3/metrics/ 指标文档端点,供官方 exporter 抓取:
echo "METRICS_KEY=q1w2e3r4-metrics" >> /etc/healthchecks
systemctl restart healthchecks-web
实测两种请求(无密钥 403,带密钥返回抓取游标 JSON):
无密钥 -> 403
{"ts": 1792166213, "max_ping_id": 11, "max_notification_id": 6, "num_unprocessed_flips": 0}
接入 Prometheus:用官方 healthchecks-exporter(社区)或自写脚本定期拉取该 JSON,num_unprocessed_flips(未处理的翻转数)持续 > 0 即 sendalerts 积压,max_ping_id 增速即 ping 流量水位。Check 级别的 up/down 总览可直接用全局 Badge 嵌入看板。
3.5 备份与恢复演练
备份:PG 在线逻辑备份(不锁表):
su postgres -c "pg_dump -p 5433 hc" > /tmp/hc-backup.sql
ls -lh /tmp/hc-backup.sql
grep -c "^CREATE TABLE" /tmp/hc-backup.sql
实测输出:
-rw-r--r-- 1 root root 72K Oct 16 15:48 /tmp/hc-backup.sql
23
恢复演练(新库验证备份可用):
echo "CREATE DATABASE hc_restore;" | su postgres -c "psql -p 5433"
su postgres -c "psql -p 5433 -d hc_restore < /tmp/hc-backup.sql" 2>&1 | tail -2
实测输出(节选):
CREATE DATABASE
ALTER TABLE
ALTER TABLE
备份策略建议:每日 pg_dump(加 --clean --if-exists 便于整库回灌),保留 7 天滚动 + 每周一份异地;/etc/healthchecks 与 hc/local_settings.py(含 SECRET_KEY)一并纳入备份——SECRET_KEY 丢失等于 API Key 全部报废。SQLite 形态更简单:停写窗口拷贝 hc.sqlite 文件,或 sqlite3 hc.sqlite ".backup '/tmp/hc.sqlite.bak'"。
3.6 数据清理
ping 记录与令牌桶随时间增长,两个清理命令实测:
cd /opt/healthchecks
/opt/venv/bin/python manage.py pruneobjects
/opt/venv/bin/python manage.py prunetokenbucket
实测输出:
Object storage is not configured
Done! Pruned 0 token bucket entries
解读:pruneobjects 清理 S3/MinIO 上的过期 ping body,未配置 S3_* 时如上直接退出;prunetokenbucket 清理限流表(0 条说明无残留)。数据库内 ping 行的保留条数由 PING_LOG_LIMIT(默认 100)控制,每次新 ping 到达时按 Check 裁剪,无需人工干预。建议给 prunetokenbucket 加每周 cron:
echo "0 4 * * 0 cd /opt/healthchecks && /opt/venv/bin/python manage.py prunetokenbucket" | crontab -
3.7 升级迁移
官方镜像部署(推荐路径,实测 v4.3 → v4.4):升级 = 换 tag + 重建,新容器启动时 pre-app hook 自动执行 migrate:
docker pull healthchecks/healthchecks:v4.4
# docker-compose.yml 中镜像 tag 改为 v4.4 后:
docker compose pull web && docker compose up -d web
实测启动日志与新库状态核对:
web-1 | running "exec:./manage.py migrate" (pre app)...
web-1 | Operations to perform:
web-1 | No migrations to apply.
升级后 checks: ['job-nightly', 'My First Check']
(v4.3 → v4.4 数据库结构兼容,迁移集相同;若某次升级有新迁移,日志里会出现 Applying <app>.<migration>... OK 行,属正常。)
源码部署升级路径(标准五步):
# 1) 备份数据库(见 3.5)
su postgres -c "pg_dump -p 5433 hc" > /tmp/hc-pre-upgrade.sql
# 2) 停服务
systemctl stop healthchecks-web healthchecks-sendalerts
# 3) 替换程序文件(保留 hc/local_settings.py 与 static-collected/)
cd /tmp && curl -LO https://github.com/healthchecks/healthchecks/archive/refs/tags/v4.5.tar.gz
tar xzf v4.5.tar.gz
rsync -a --exclude 'hc/local_settings.py' --exclude 'static-collected' healthchecks-4.5/ /opt/healthchecks/
# 4) 更新依赖并迁移
/opt/venv/bin/pip install -r /opt/healthchecks/requirements.txt
cd /opt/healthchecks && /opt/venv/bin/python manage.py migrate
# 5) 启动并验证
systemctl start healthchecks-web healthchecks-sendalerts
curl -s http://127.0.0.1:8000/accounts/login/ -o /dev/null -w "%{http_code}\n"
⚠️ 注意:跨多个 minor 版本升级时,逐版本升(4.2→4.3→4.4)比直接跳级稳;每次升级前
pg_dump是底线。版本变更后用manage.py shell -c "import hc; print(hc.__version__)"核对实际代码版本。
3.8 服务健康巡检脚本
一条命令巡检全栈(可直接放进 cron 或 CI):
systemctl is-active healthchecks-web healthchecks-sendalerts
curl -s http://127.0.0.1:8000/api/v3/status/ -o /dev/null -w "status api -> %{http_code}\n"
su postgres -c "pg_isready -p 5433 -d hc"
实测输出:
active
active
status api -> 200
/tmp/pg_isready.KFQevT:5433 - accepting connections
四、常见问题(FAQ)
Q1:告警邮件发送失败,日志报 SMTPRecipientsRefused?
实测报错(sendalerts 日志中):
smtplib.SMTPRecipientsRefused: {'admin@example.org': (550, b'5.1.1 Recipient rejected')}
原因就是出站 SMTP 指到了 Healthchecks 自家的入站 smtpd(它只收 Check 地址)。解决:出站 EMAIL_HOST 指向真正的邮件服务器;调试抓包用通用调试服务器(python -m aiosmtpd -n -l 127.0.0.1:2525)。区分口诀:收任务邮件用 smtpd(入站),发告警邮件用 EMAIL_HOST(出站)。
Q2:num_unprocessed_flips 一直大于 0?
翻转事件积压,说明 sendalerts 没在跑或跑挂了。排查:systemctl is-active healthchecks-sendalerts;看日志 journalctl -u healthchecks-sendalerts -n 100;若频繁崩溃重启,确认 /etc/healthchecks 权限(600,hc 用户可读)与数据库连接参数。
Q3:手动执行管理命令报 AssertionError: No SMTP configuration?
systemd 环境文件只对服务进程生效,shell 手动执行要自己加载:set -a; . /etc/healthchecks; set +a; manage.py <命令>(3.3 实测踩过)。Docker 部署用 docker compose run --rm web ... 自动继承容器环境,无此问题。
Q4:升级后页面 500?
三个高频原因:① 漏跑 migrate(新版本有新迁移);② 依赖没装全(requirements.txt 之外,pruneobjects/S3 需要 pip install minio,漏装实测报 ModuleNotFoundError: No module named 'minio');③ local_settings.py 覆盖了新版已改名的字段。按 3.7 的五步走并用 manage.py check 预检。
Q5:PostgreSQL 版本不满足报错?
django.db.utils.NotSupportedError: PostgreSQL 15 or later is required (found 14.24).——Ubuntu 22.04 默认源是 PG 14,用 PGDG 仓库装 16(详见《Healthchecks v4.4 Ubuntu 22.04 安装指南》4.2 与 FAQ)。
Q6:ping 记录太多,怎么瘦身?
单 Check 保留条数由 PING_LOG_LIMIT(默认 100)自动裁剪,无需手工删;S3 body 由 pruneobjects 清。表膨胀严重时对 api_ping 等表做 VACUUM ANALYZE;再不够就降低 PING_BODY_LIMIT 从源头减负。
Q7:Docker 部署怎么执行这些管理命令?
把本文的 manage.py <命令> 换成 docker compose run --rm web /opt/healthchecks/manage.py <命令>;sendalerts/sendreports/smtpd 镜像内置自动运行,无需也不应再手工启动;日志统一看 docker compose logs web。
五、参考链接
- 官方自托管运维文档:https://healthchecks.io/docs/self_hosted/
- 管理 API:https://healthchecks.io/docs/api/
- sendalerts/sendreports 源码(v4.4):https://github.com/healthchecks/healthchecks/tree/v4.4/hc/api/management/commands
- 官方 Docker 编排说明:https://github.com/healthchecks/healthchecks/blob/v4.4/docker/README.md
- 本系列其他篇:《Healthchecks v4.4 Ubuntu 22.04 安装指南》《Healthchecks v4.4 Docker Compose 部署指南》《Healthchecks v4.4 快速入门与集成示例》《Healthchecks v4.4 配置参数详解》