Gatus 运维手册
覆盖 Gatus v5.37.0 日常巡检、备份恢复、监控告警、扩容缩容、升级回滚与故障排查的完整运维闭环,全部命令与回显实测照抄。
Gatus 运维手册
> 目标:覆盖 Gatus v5.37.0 日常巡检、备份恢复、监控告警、扩容缩容、升级回滚与故障排查的完整运维闭环,全部命令与回显均在真实环境实测照抄。已在 Ubuntu 22.04(x86_64,Gatus v5.37.0,systemd 托管)实测通过。
一、环境信息
本篇所有操作均在以下环境实测,回显逐条照抄:
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Gatus 版本:v5.37.0(二进制
/usr/local/bin/gatus,50876715 字节,版本确认方法见 六、6.1) - 运行方式:systemd 服务
gatus.service(Restart=on-failure,RestartSec=5),环境变量GATUS_CONFIG_PATH=/opt/data/gatus-server/config.yaml - 存储:SQLite(
/opt/data/gatus-server/data/data.db,WAL 模式),sqlite3 3.37.2 - 端点:3 个 HTTP 端点(
core_nginx-health15s、core_nginx-missing1m、自监控ops_gatus-self30s)+ 1 个外部推送端点(core_ext-agent) - 告警渠道:custom(HTTP POST,配置见《Gatus 配置参数详解》)
- 实测期间的配置热重载、告警触发/解除、升级与回滚均为真实发生并留有日志
二、日常巡检
2.1 服务与端口巡检
systemctl status gatus --no-pager -l | head -12
实测输出(节选,CGroup 行略):
● gatus.service - Gatus Health Dashboard
Loaded: loaded (/etc/systemd/system/gatus.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2026-10-17 20:45:56 UTC; 15min ago
Main PID: 3433 (gatus)
Tasks: 14 (limit: 5753)
Memory: 13.4M
CPU: 390ms
进程级内存与存活时间用 ps 观察(与 systemd 的 cgroup 统计口径不同,建议巡检时固定用同一种命令对比历史基线):
ps -o pid,rss,etime,args -p $(pidof gatus)
实测输出:
PID RSS ELAPSED COMMAND
3433 37732 15:28 /usr/local/bin/gatus
端口探活:最小化安装的系统常无 ss/netstat,直接用 HTTP 探测最可靠(进程在但不服务时也能发现,见 七、7.1):
curl -s -o /dev/null -m 3 -w '%{http_code}\n' http://127.0.0.1:8080/
实测输出:
200
2.2 拨测结果巡检
一条命令汇总所有端点的最近一次结果(API 细节见《Gatus API 使用详解》):
curl -s http://127.0.0.1:8080/api/v1/endpoints/statuses | python3 -c "
import json,sys
for ep in json.load(sys.stdin):
r=ep['results'][-1] if ep['results'] else None
print('%-24s %-6s %s' % (ep['key'], 'OK' if r and r.get('success') else 'FAIL', r['timestamp'] if r else 'n/a'))
"
实测输出:
core_ext-agent OK 2026-10-17T20:50:54.013883228Z
core_nginx-health OK 2026-10-17T21:17:44.093950836Z
core_nginx-missing OK 2026-10-17T21:17:44.315556424Z
ops_gatus-self OK 2026-10-17T21:17:14.541862094Z
巡检关注两点:FAIL 的端点,以及时间戳停滞的端点——core_ext-agent 是外部推送端点,其最后结果停在 20:50:54 说明外部推送方已停止推送(正常端点时间戳应随拨测间隔推进)。
2.3 日志巡检
journalctl -u gatus --no-pager -n 5
实测输出:
Oct 17 21:00:32 970d253b8646 gatus[3433]: 2026/10/17 21:00:32 [watchdog.executeEndpoint] Monitored group=core; endpoint=nginx-health; key=core_nginx-health; success=true; errors=0; duration=0s
Oct 17 21:00:47 970d253b8646 gatus[3433]: 2026/10/17 21:00:47 [watchdog.executeEndpoint] Monitored group=core; endpoint=nginx-health; key=core_nginx-health; success=true; errors=0; duration=0s
Oct 17 21:01:02 970d253b8646 gatus[3433]: 2026/10/17 21:01:02 [watchdog.executeEndpoint] Monitored group=core; endpoint=nginx-health; key=core_nginx-health; success=true; errors=0; duration=0s
Oct 17 21:01:02 970d253b8646 gatus[3433]: 2026/10/17 21:01:02 [watchdog.executeEndpoint] Monitored group=core; endpoint=nginx-missing; key=core_nginx-missing; success=true; errors=0; duration=0s
Oct 17 21:01:17 970d253b8646 gatus[3433]: 2026/10/17 21:01:17 [watchdog.executeEndpoint] Monitored group=core; endpoint=nginx-health; key=core_nginx-health; success=true; errors=0; duration=1ms
每行含 success=、errors=、duration=,巡检时抓失败行即可:
journalctl -u gatus --no-pager --since "2026-10-17 20:45" | grep -c "has been TRIGGERED"
journalctl -u gatus --no-pager --since "2026-10-17 20:45" | grep -c "has been RESOLVED"
实测输出(触发 4 行 = 2 次事故各打 2 行日志,解除 2 行):
4
2
2.4 存储巡检
ls -la /opt/data/gatus-server/data/
sqlite3 /opt/data/gatus-server/data/data.db "SELECT e.endpoint_key, COUNT(r.endpoint_result_id) FROM endpoint_results r JOIN endpoints e ON e.endpoint_id=r.endpoint_id GROUP BY 1;"
实测输出:
-rw-r--r-- 1 root root 114688 Oct 17 21:16 data.db
-rw-r--r-- 1 root root 32768 Oct 17 21:16 data.db-shm
-rw-r--r-- 1 root root 692192 Oct 17 21:16 data.db-wal
core_ext-agent|4
core_nginx-health|135
core_nginx-missing|43
ops_gatus-self|24
巡检要点:-wal 文件随写入波动(实测 667KB~992KB 均出现过)属正常现象,SQLite 以 WAL 模式运行(PRAGMA journal_mode 实测返回 wal);数据文件大小受 storage.maximum-number-of-results 保留上限控制(实测本例 500),行数不应无限增长。
2.5 巡检基线(实测参考值)
| 项目 | 命令 | 实测基线(3~13 个端点) |
|---|---|---|
| 服务状态 | systemctl is-active gatus | active |
| Web 探活 | curl -w '%{http_code}' | 200 |
| 进程 RSS | ps -o rss= -p $(pidof gatus) | 36.8MB~42.5MB(随端点数浮动,见 五、5.1) |
| cgroup 内存 | systemctl status 的 Memory 行 | 13.4M |
| 数据文件 | ls -la data/data.db | 96KB~123KB(保留 500 条/端点内) |
| WAL 文件 | ls -la data/data.db-wal | 0~1MB 波动 |
三、备份与恢复
3.1 备份范围与 WAL 陷阱
需要备份的只有两样:配置文件与 SQLite 数据文件。直接 cp 数据文件有丢数据风险:Gatus 以 WAL 模式运行,最近的写入在 data.db-wal 中尚未合并(实测 WAL 一度达 992952 字节,而主文件仅 98304 字节),只拷主文件会丢掉 WAL 里的数据。两种安全做法:
- 在线备份:
sqlite3 .backup(推荐,不停服务); - 冷备:
systemctl stop gatus后拷贝整个data/目录(含 WAL)。
3.2 在线备份(实测)
sqlite3 /opt/data/gatus-server/data/data.db ".backup '/tmp/gatus-data-backup.db'"
ls -la /tmp/gatus-data-backup.db
sqlite3 /tmp/gatus-data-backup.db "PRAGMA integrity_check; SELECT COUNT(*) FROM endpoint_results;"
实测输出:
-rw-r--r-- 1 root root 110592 Oct 17 21:02 /tmp/gatus-data-backup.db
ok
114
.backup 命令已将 WAL 内容合并进备份文件(110592 字节 > 主文件 98304 字节),integrity_check 返回 ok,服务全程未中断。
3.3 配置备份
cp -a /opt/data/gatus-server/config.yaml /tmp/gatus-config-$(date +%F).yaml
配置文件含告警渠道 token 等敏感信息,备份文件的权限与存放位置按敏感数据处理(本例实测 ls -la 显示 -rw-r--r--,生产建议收紧为 600)。
3.4 恢复演练(实测)
用 3.2 的备份文件完整演练一次恢复:
systemctl stop gatus
rm -f /opt/data/gatus-server/data/data.db-wal /opt/data/gatus-server/data/data.db-shm
cp /tmp/gatus-data-backup.db /opt/data/gatus-server/data/data.db
systemctl start gatus
验证(实测输出):
systemctl is-active gatus
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/api/v1/endpoints/statuses
sqlite3 /opt/data/gatus-server/data/data.db "SELECT COUNT(*) FROM endpoint_results;"
active
200
116
恢复成功:行数从备份时刻的 114 继续增长到 116(服务启动后立即补了两轮拨测)。注意恢复前必须删除旧 WAL/SHM 文件,否则旧 WAL 会与新恢复的主文件错配。
3.5 备份策略建议
- 配置文件:每次修改前后各存一版(本篇排障多次依赖
/tmp/config-good.yaml式的快速回退),并纳入定期备份; - 数据文件:
sqlite3 .backup每日一次即可(数据是拨测历史,丢失只影响在线率曲线,不影响功能);历史在线率也可改从 API 导出归档(见《Gatus API 使用详解》); - 升级前:二进制、配置、数据三样全部备份(见 六、6.6)。
四、监控告警
4.1 给 Gatus 配自监控端点
Gatus 自身的 Web 服务停摆不会体现在任何业务端点上(见 七、7.1 的实测事故),必须让 Gatus 拨测自己。在 config.yaml 的 endpoints: 列表中加入(本环境实测配置):
- name: gatus-self
group: ops
url: http://127.0.0.1:8080/api/v1/endpoints/statuses
interval: 30s
conditions:
- "[STATUS] == 200"
alerts:
- type: custom
description: "Gatus 自监控异常(Web 停摆)"
保存后无需重启,配置监听到变更后自动生效(实测日志):
Oct 17 21:03:17 970d253b8646 gatus[3717]: 2026/10/17 21:03:17 [main.listenToConfigurationFileChanges] Configuration file has been modified
Oct 17 21:03:17 970d253b8646 gatus[3717]: 2026/10/17 21:03:17 [watchdog.monitorEndpoint] Canceling current execution of group=core; endpoint=nginx-health; key=core_nginx-health
Oct 17 21:03:17 970d253b8646 gatus[3717]: 2026/10/17 21:03:17 [controller.Handle] Server has shut down successfully
Oct 17 21:03:17 970d253b8646 gatus[3717]: 2026/10/17 21:03:17 [watchdog.monitorEndpoint] Canceling current execution of group=core; endpoint=nginx-missing; key=core_nginx-missing
Oct 17 21:03:18 970d253b8646 gatus[3717]: 2026/10/17 21:03:18 [config.LoadConfiguration] Reading configuration from configFile=/opt/data/gatus-server/config.yaml
Oct 17 21:03:18 970d253b8646 gatus[3717]: 2026/10/17 21:03:18 [config.ValidateEndpointsConfig] Validated 3 endpoints
Oct 17 21:03:18 970d253b8646 gatus[3717]: 2026/10/17 21:03:18 [config.ValidateEndpointsConfig] Validated 1 external endpoints
Oct 17 21:03:18 970d253b8646 gatus[3717]: 2026/10/17 21:03:18 [controller.Handle] Listening on 0.0.0.0:8080
新端点随即出现在 API 中(实测 ops_gatus-self 首条结果 success: true、hostname: "127.0.0.1"、duration: 2517031 纳秒)。
注意热重载序列中的 Server has shut down successfully:每次重载都会先关 Web 再重启,这是一切热重载事故的源头(见 七、7.1)。此外配置变更的监听延迟不固定(实测同环境从 1 秒到约 57 秒不等),改配置后以这条日志为准,见 七、7.4。
4.2 自监控告警实录(实测)
2026-10-17 21:06 排障实验中故意注入坏配置,Web 停摆,自监控端点立刻抓到并触发告警:
Oct 17 21:06:55 970d253b8646 gatus[3717]: 2026/10/17 21:06:55 [watchdog.handleAlertsToTrigger] Sending custom alert because alert for endpoint with key=ops_gatus-self with description='Gatus 自监控异常(Web 停摆)' has been TRIGGERED
Oct 17 21:06:55 970d253b8646 gatus[3717]: 2026/10/17 21:06:55 [watchdog.handleAlertsToTrigger] Sending initial custom alert because alert for endpoint=gatus-self with description='Gatus 自监控异常(Web 停摆)' has been TRIGGERED
配置修复后服务自愈,告警自动解除:
Oct 17 21:08:26 970d253b8646 gatus[3717]: 2026/10/17 21:08:26 [main.listenToConfigurationFileChanges] Configuration file has been modified
Oct 17 21:08:27 970d253b8646 gatus[3717]: 2026/10/17 21:08:27 [config.LoadConfiguration] Reading configuration from configFile=/opt/data/gatus-server/config.yaml
Oct 17 21:08:27 970d253b8646 gatus[3717]: 2026/10/17 21:08:27 [controller.Handle] Listening on 0.0.0.0:8080
Oct 17 21:08:57 970d253b8646 gatus[3717]: 2026/10/17 21:08:57 [watchdog.handleAlertsToResolve] Sending custom alert because alert for endpoint with key=ops_gatus-self with description='Gatus 自监控异常(Web 停摆)' has been RESOLVED
TRIGGERED 21:06:55 → RESOLVED 21:08:57,闭环完整。触发态持久化在 SQLite 中(endpoint_alerts_triggered 表),进程重启不会丢告警状态。
4.3 Prometheus 指标
配置 metrics: true 后 GET /metrics 暴露 Prometheus 指标。实测指标族共 5 个(重启后立刻抓取):
# HELP gatus_results_code_total Total number of results by code
# TYPE gatus_results_code_total counter
# HELP gatus_results_connected_total Total number of results in which a connection was successfully established
# TYPE gatus_results_connected_total counter
# HELP gatus_results_duration_seconds Duration of the request in seconds
# TYPE gatus_results_duration_seconds gauge
# HELP gatus_results_endpoint_success Displays whether or not the endpoint was a success
# TYPE gatus_results_endpoint_success gauge
# HELP gatus_results_total Number of results per endpoint
# TYPE gatus_results_total counter
实测系列样例:
gatus_results_code_total{code="200",group="core",key="core_nginx-health",name="nginx-health",type="HTTP"} 1
gatus_results_duration_seconds{group="core",key="core_nginx-health",name="nginx-health",type="HTTP"} 0.00094434
gatus_results_endpoint_success{group="core",key="core_nginx-health",name="nginx-health",type="HTTP"} 1
gatus_results_total{group="core",key="core_nginx-health",name="nginx-health",success="true",type="HTTP"} 1
实测要点:grep -cE '^gatus_' 重启后为 10(2 个被拨测端点 × 5 个指标族);counter 类指标随进程运行累计,进程重启后归零,长期趋势图须用 rate()/increase() 而非绝对值;外部推送端点(external-endpoints)不产生这些 HTTP 拨测指标(实测确认)。
4.4 告警渠道与维护窗口
- 告警渠道配置与触发阈值实测见《Gatus 配置参数详解》(custom 渠道全链路 TRIGGERED/RESOLVED 实测);
- 端点侧必须显式声明
alerts: - type: custom才会告警,default-alert只是模板(实测踩坑记录见同篇); - 维护窗口(
maintenance段)只抑制告警不暂停拨测(实测),升级期间不希望收告警时用它。
五、扩容缩容
5.1 扩容实测(3 端点 → 13 端点)
向配置追加 10 个端点(group: bench,interval: 10s,指向同一目标),热重载生效后实测:
ps -o rss= -p $(pidof gatus) # 扩容前:36856
sleep 45
ps -o rss= -p $(pidof gatus) # 扩容后:40092
curl -s http://127.0.0.1:8080/api/v1/endpoints/statuses | python3 -c "import json,sys; d=json.load(sys.stdin); print(len(d), sum(len(x['results']) for x in d if x['group']=='bench'))"
sqlite3 /opt/data/gatus-server/data/data.db "SELECT COUNT(*) FROM endpoint_results;"
实测输出:
36856
40092
14 30
176
结论:10 个 10s 间隔端点(每秒约 1 次拨测)增加 RSS 约 3.2MB,45 秒内产生 30 条结果,endpoint_results 增长到 176 行。每增加 10 个高频端点按个位数 MB 估算内存即可(官方 README 对资源消耗的描述为 "negligibly small",实测相符)。
5.2 缩容与内存释放
移除这 10 个端点后实测:端点数回落到 4,但 RSS 不回落(实测仍为 42484KB)——Go 运行时保留已分配内存,这是正常现象。判断依据应看增量后的稳态值;确需立即释放(如长期驻留了扩容期峰值)就重启服务:
systemctl restart gatus && sleep 5 && ps -o rss= -p $(pidof gatus)
5.3 存储保留与手工收缩
保留上限由 storage.maximum-number-of-results / maximum-number-of-events 控制(默认 100/50),改小不会立即收缩历史数据(实测行为见《Gatus 配置参数详解》)。需要立即收缩时停服手工处理(实测):
systemctl stop gatus
sqlite3 /opt/data/gatus-server/data/data.db "PRAGMA wal_checkpoint(TRUNCATE); DELETE FROM endpoint_results WHERE endpoint_id=(SELECT endpoint_id FROM endpoints WHERE endpoint_key='core_nginx-health') AND endpoint_result_id NOT IN (SELECT endpoint_result_id FROM endpoint_results WHERE endpoint_id=(SELECT endpoint_id FROM endpoints WHERE endpoint_key='core_nginx-health') ORDER BY timestamp DESC LIMIT 50); VACUUM; PRAGMA page_count; PRAGMA freelist_count;"
ls -la /opt/data/gatus-server/data/
systemctl start gatus
实测输出:
0|0|0
28
0
-rw-r--r-- 1 root root 114688 Oct 17 21:16 data.db
验证:服务恢复 active、API 返回 200,core_nginx-health 行数实测 51(保留 50 + 启动后新一轮)。实测结论:WAL 截断是主要回收手段(WAL 从 692192 字节归零);Gatus 自身的周期清理使 freelist 常年为 0,VACUUM 在小库上收益有限(page_count 30→28),大批量手工删除后才明显。
六、升级与回滚
6.1 版本确认
Gatus 没有 --version 参数(实测传参只会正常启动服务),也没有版本 API(实测 curl http://127.0.0.1:8080/api/v1/version 返回 404 与 Cannot GET /api/v1/version)。可靠的两条确认途径:
途径一,go version -m(需要 Go 环境,实测输出):
go version -m /usr/local/bin/gatus | head -3
/usr/local/bin/gatus: go1.26.9
path github.com/TwiN/gatus/v5
mod github.com/TwiN/gatus/v5 v5.37.0 h1:LlOlToOmKIqNaffPQzGq9FBiSi998jmcCobgoi/t0V8=
途径二,无需任何工具:启动失败时的 panic 堆栈自带版本(实测日志):
/root/go/pkg/mod/github.com/!twi!n/gatus/v5@v5.37.0/main.go:32
6.2 官方分发形态与编译环境
官方 GitHub Release 不提供预编译二进制(实测 v5.37.0 release 资产列表仅有 Source code (zip) 与 Source code (tar.gz) 两项),官方 README 的二进制安装方式即编译安装:
go install github.com/TwiN/gatus/v5@latest
因此升级 = 用 Go 编译新版本并替换二进制。编译环境实测(Ubuntu 22.04 上安装 Go 1.26.9):
curl -sL -o /tmp/go1.26.9.linux-amd64.tar.gz https://mirrors.aliyun.com/golang/go1.26.9.linux-amd64.tar.gz
tar -C /usr/local -xzf /tmp/go1.26.9.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version
实测输出:
go version go1.26.9 linux/amd64
编译走模块代理加速:export GOPROXY=https://goproxy.cn,direct。
6.3 升级演练环境(隔离实测)
以下升级与回滚均在独立演练目录完成(端口 8081、独立 SQLite,主服务不受影响,演练后主服务实测仍为 active/200)。演练配置:
web:
port: 8081
storage:
type: sqlite
path: /opt/gatus-upgrade-lab/data.db
endpoints:
- name: lab-target
group: lab
url: http://gatus-5370-target-nginx/health
interval: 10s
conditions:
- "[STATUS] == 200"
6.4 升级实测(v5.36.0 → v5.37.0)
先编译安装上一版本 v5.36.0 并运行(实测版本信息与运行状态):
go install github.com/TwiN/gatus/v5@v5.36.0
go version -m /root/go/bin/gatus | grep "mod "
实测输出:
mod github.com/TwiN/gatus/v5 v5.36.0 h1:htpXnA4ESSqarxy1hRhrQLsyfp6Q30vb3X/yDC3Cb80=
GATUS_CONFIG_PATH=/opt/gatus-upgrade-lab/config.yaml /opt/gatus-upgrade-lab/gatus-v5.36.0 &
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8081/api/v1/endpoints/statuses
sqlite3 /opt/gatus-upgrade-lab/data.db "SELECT COUNT(*) FROM endpoint_results;"
实测输出(运行约 12 秒后):
200
2
然后编译 v5.37.0(实测 go version -m 输出 mod github.com/TwiN/gatus/v5 v5.37.0 h1:LlOlToOmKIqNaffPQzGq9FBiSi998jmcCobgoi/t0V8=),停旧进程、换二进制、原库重启:
GATUS_CONFIG_PATH=/opt/gatus-upgrade-lab/config.yaml /opt/gatus-upgrade-lab/gatus-v5.37.0 &
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8081/api/v1/endpoints/statuses
sqlite3 /opt/gatus-upgrade-lab/data.db "SELECT COUNT(*) FROM endpoint_results;"
实测输出:
200
4
升级实测结论:同一数据文件直接跨版本启动,无迁移报错、无数据丢失(2 行历史保留,继续写入 2 行),启动日志仅 Listening on 0.0.0.0:8081,与《Gatus Docker Compose 部署指南》中升级版本的实测行为一致。
6.5 回滚实测(v5.37.0 → v5.36.0)
同一数据文件直接换回 v5.36.0 二进制启动:
GATUS_CONFIG_PATH=/opt/gatus-upgrade-lab/config.yaml /opt/gatus-upgrade-lab/gatus-v5.36.0 &
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8081/api/v1/endpoints/statuses
sqlite3 /opt/gatus-upgrade-lab/data.db "SELECT COUNT(*) FROM endpoint_results;"
实测输出:
200
6
实测结论:v5.36.0 可正常打开 v5.37.0 写过的数据文件并继续拨测(日志恢复 Monitored group=lab; ... success=true),同 5.x 小版本系列内二进制回滚可行。跨大版本回滚前仍应先做 3、的完整备份,不要依赖未实测的降级路径。
6.6 主服务标准升级步骤
结合以上实测,主服务升级清单(版本号替换为目标版本):
# 1. 备份(配置+数据+二进制,见 三、)
cp -a /opt/data/gatus-server/config.yaml /tmp/gatus-config-$(date +%F).yaml
sqlite3 /opt/data/gatus-server/data/data.db ".backup '/tmp/gatus-data-pre-upgrade.db'"
cp -a /usr/local/bin/gatus /usr/local/bin/gatus.bak
# 2. 编译新版本并核对版本号
go install github.com/TwiN/gatus/v5@v5.38.0
go version -m /root/go/bin/gatus | grep "mod "
# 3. 替换并重启
systemctl stop gatus
install -m 755 /root/go/bin/gatus /usr/local/bin/gatus
systemctl start gatus
# 4. 验证清单
systemctl is-active gatus # active
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/api/v1/endpoints/statuses # 200
sqlite3 /opt/data/gatus-server/data/data.db "SELECT COUNT(*) FROM endpoint_results;" # 行数延续
journalctl -u gatus --no-pager -n 20 | grep -iE "error|panic" # 无异常
回滚 = systemctl stop gatus && cp -a /usr/local/bin/gatus.bak /usr/local/bin/gatus && systemctl start gatus(6.5 实测可行)。
七、故障排查手册
7.1 进程 active 但 8080 拒绝连接(热重载失败停摆)
现象:systemctl is-active 返回 active,curl 却连接拒绝。实测复现(向配置追加一个与现有 external-endpoints 重名的条目):
Oct 17 21:06:56 970d253b8646 gatus[3717]: 2026/10/17 21:06:56 [config.LoadConfiguration] Reading configuration from configFile=/opt/data/gatus-server/config.yaml
Oct 17 21:06:56 970d253b8646 gatus[3717]: 2026/10/17 21:06:56 [main.listenToConfigurationFileChanges] Failed to load new configuration: error parsing config: invalid external endpoint core_ext-agent: name and group combination must be unique
Oct 17 21:06:56 970d253b8646 gatus[3717]: 2026/10/17 21:06:56 [main.listenToConfigurationFileChanges] The configuration file was updated, but it is not valid. The old configuration will continue being used.
systemctl is-active gatus
curl -s -m 3 -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/
实测输出:
active
000
根因:热重载流程是「先关 Web → 加载新配置」,校验失败后旧配置继续拨测,但 Web 服务不再重启,UI 与 API 全部停摆。行为链完整实测见《Gatus 配置参数详解》(skip-invalid-config-update: true 已配置时同样发生)。此时唯一可靠的捕获手段是 4.1 的自监控端点——本次事故中它实时触发了告警(4.2 实录)。
处置:把配置改对(或恢复备份),监听到正确文件后服务自愈,无需重启进程(实测 21:08:27 自动重新 Listening on 0.0.0.0:8080,curl 恢复 200)。应急快速恢复用配置备份:
cp /tmp/config-good.yaml /opt/data/gatus-server/config.yaml
预防:改配置前先在临时目录跑 GATUS_CONFIG_PATH=<新文件> gatus 验证能正常启动;热重载生效前盯一眼日志里有无 Failed to load new configuration。
7.2 启动 panic: configuration file not found
配置文件路径不存在时启动直接 panic(实测:停服后把配置文件移走再启动):
Oct 17 21:09:42 970d253b8646 gatus[3874]: panic: configuration file not found
Oct 17 21:09:42 970d253b8646 gatus[3874]: goroutine 1 [running]:
Oct 17 21:09:42 970d253b8646 gatus[3874]: main.main()
Oct 17 21:09:42 970d253b8646 gatus[3874]: /root/go/pkg/mod/github.com/!twi!n/gatus/v5@v5.37.0/main.go:32 +0x209
Oct 17 21:09:42 970d253b8646 systemd[1]: gatus.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Oct 17 21:09:42 970d253b8646 systemd[1]: gatus.service: Failed with result 'exit-code'.
两个实测细节值得注意:
GATUS_CONFIG_PATH指向的文件名必须精确——把config.yaml误命名为gatus.yml等都会触发本 panic(实测《Gatus Docker Compose 部署指南》同款案例);- 在
Restart=on-failure下这不是一次性失败:每 5 秒重启再 panic,unit 状态停留在activating(实测systemctl is-active与is-failed均返回activating),基于is-failed的监控不会报警,必须靠端口探活。
处置:恢复配置文件后 systemctl restart gatus,实测立即恢复 active 与 200。
7.3 TLS 证书校验失败(x509)
拨测自签/过期证书的目标时,端点失败且 UI 显示 errors(实测 ops_tls-badssl 端点拨测 self-signed.badssl.com,API 返回照抄):
{
"hostname": "self-signed.badssl.com",
"duration": 905156670,
"errors": [
"Get \"https://self-signed.badssl.com/\": tls: failed to verify certificate: x509: certificate signed by unknown authority"
],
"conditionResults": [
{
"condition": "[STATUS] (0) == 200",
"success": false
}
],
"success": false,
"timestamp": "2026-10-17T21:12:19.875776064Z"
}
x509: certificate signed by unknown authority 即系统 CA 库不信任该证书链,且 status 渲染为 (0)(未收到 HTTP 响应)。处置分两种:
- 内部自签服务:给该端点加
client: {insecure: true}跳过校验(仅限内网可信目标,参数见《Gatus 配置参数详解》); - 公共站点报错:说明本机系统 CA 过旧,
apt install --only-upgrade ca-certificates升级。注意 Go 程序在启动时加载 CA 池,升级 CA 后必须重启 Gatus 进程才生效(实测:升级 CA 并更新证书后不重启仍失败,重启后恢复)。
7.4 改了配置迟迟不生效(配置监听延迟)
配置变更监听的延迟不固定,实测同环境三次变更的「写入 → 日志出现 Configuration file has been modified」间隔分别为约 57 秒、11 秒、1 秒。改配置后:
journalctl -u gatus --no-pager -n 10 | grep -E "modified|Failed to load|Listening"
看到 modified 且无 Failed to load 才算生效;对生效时间敏感的变更(如调整 interval)宁可 systemctl restart gatus。
7.5 存储文件一直不变小
maximum-number-of-results 改小后旧数据由后台周期清理,不立即收缩;手工清理与 WAL 截断见 五、5.3 实测。日常巡检以 2.4 的行数统计为准,只要行数在保留上限内即正常。
八、常见问题
Q1:Web 服务监听在哪,公网能直接访问吗
实测启动日志为 Listening on 0.0.0.0:8080(全地址监听)。生产环境务必配合防火墙限制来源,并启用 Basic 认证(实测 401/200 行为见《Gatus 配置参数详解》)或置于反向代理之后。
Q2:巡检时 systemctl status 显示的 Memory 与 ps 的 RSS 差很多
两个口径不同(cgroup 统计 vs 进程常驻内存),实测分别为 13.4M 与约 37MB。趋势判断选定一种命令固定对比即可,勿混用。
Q3:重启进程后 Prometheus 图表断了
counter 类指标随进程重启归零(4.3 实测),图表层用 rate()/increase() 处理,重启造成的断点属预期行为。
Q4:ss、netstat 都不存在怎么探活
最小化系统常不带这些工具,直接 curl -s -o /dev/null -m 3 -w '%{http_code}\n' http://127.0.0.1:8080/(2.1 实测),比端口工具更能发现「进程在但不服务」的假活状态。
九、参考链接
- 官方文档首页:https://gatus.io/docs
- 官方 README(存储/告警/安装章节):https://github.com/TwiN/gatus#readme
- 存储配置参考:https://github.com/TwiN/gatus#storage
- 版本发布列表:https://github.com/TwiN/gatus/releases
- 本站配套:《Gatus 介绍与选型指南》《Gatus Docker Compose 部署指南》《Gatus 配置参数详解》《Gatus API 使用详解》