Gatus:主动健康检查 + 可视化状态页 + 多通道告警
你有没有遇到过这种情况——凌晨 3 点,用户在群里反馈服务挂了,而你这边一个告警都没有?Prometheus 的 Alertmanager 安静如鸡,因为"没有流量就没有错误"。等客户把电话打到老板那里,你才知道负载均衡器早就挂了。
这不是段子,这是很多团队的日常。传统监控依赖现有流量触发告警,如果没人访问,错误就没人知道。
今天介绍的 Gatus 就是为了解决这个问题而生的。它不依赖流量,而是主动探测你的每一个服务端点,在用户受到影响之前就告诉你哪里出了问题。
Gatus 是什么
Gatus 是一个用 Go 编写的 开发者友好的健康状态监控面板,GitHub 上 10K+ Star。它支持 HTTP、ICMP(ping)、TCP、DNS、SSH、STARTTLS、gRPC、WebSocket 等多种协议的健康检查,并且内置了 40+ 种告警通道——从 Slack、Discord、Telegram 到 PagerDuty、Twilio,几乎你能想到的通知方式都支持。
一句话总结:Gatus = 主动健康检查 + 可视化状态页 + 多通道告警。
一个 Docker 命令就能跑起来:
1docker run -p 8080:8080 --name gatus ghcr.io/twin/gatus:stable
访问 http://localhost:8080,你就能看到一个暗色主题的健康状态面板。
为什么不用 Prometheus Alertmanager
这是 Gatus 作者在 README 里直接回答的第一个问题。他的观点很直接:
Prometheus、CloudWatch、Splunk 这些工具都依赖现有流量来发现问题。如果负载均衡器挂了,没有流量经过,你的指标系统根本不会报错。客户端已经在遭受损失了,你却毫不知情。
Gatus 的思路完全不同——主动探测。你为每个功能配置健康检查端点,Gatus 按照设定的间隔主动去探测,不需要等用户触发。这意味着你能在用户感知到问题之前就收到告警。
一个简单的判断标准:如果你的负载均衡器现在突然挂掉,你现有的告警系统会触发吗?如果答案是"不确定",那你可能需要 Gatus。
核心特性
灵活的 Conditions 语法
这是 Gatus 最强大的地方。它不只是检查 HTTP 状态码,你还可以对响应体、响应时间、证书过期时间、域名过期时间、DNS 返回码等设置条件:
1endpoints:
2 - name: website
3 url: "https://twin.sh/health"
4 interval: 5m
5 conditions:
6 - "[STATUS] == 200" # 状态码必须是 200
7 - "[BODY].status == UP" # JSON 响应中 status 字段必须是 UP
8 - "[RESPONSE_TIME] < 300" # 响应时间必须小于 300ms
支持的占位符包括:
| 占位符 | 含义 | 示例 |
|---|---|---|
[STATUS] |
HTTP 状态码 | 404 |
[RESPONSE_TIME] |
响应时间(ms) | 10 |
[BODY] |
响应体,支持 JSONPath | {"name":"john"} |
[CONNECTED] |
是否成功连接 | true |
[CERTIFICATE_EXPIRATION] |
证书过期剩余时间 | 48h |
[DOMAIN_EXPIRATION] |
域名过期剩余时间 | 720h |
[IP] |
目标 IP 地址 | 10.0.0.1 |
[DNS_RCODE] |
DNS 返回状态 | NOERROR |
还有几个内置函数:
len([BODY].data) < 5— 数组长度判断has([BODY].errors) == false— 字段是否存在[STATUS] == any(200, 429)— 多值匹配[BODY].name == pat(john*)— 模式匹配
这套语法足够灵活,你甚至可以用它来做用户验收测试(UAT)。
Suite:端到端的工作流监控
这是 Gatus 的一个 Alpha 功能,但非常实用。Suite 允许你把多个端点串联起来,前一个请求的返回值可以作为下一个请求的参数:
1suites:
2 - name: item-crud-workflow
3 interval: 5m
4 context:
5 price: "19.99"
6 endpoints:
7 # 第一步:创建商品
8 - name: create-item
9 url: https://api.example.com/items
10 method: POST
11 body: '{"name": "Test Item", "price": "[CONTEXT].price"}'
12 conditions:
13 - "[STATUS] == 201"
14 - "len([BODY].id) > 0"
15 store:
16 itemId: "[BODY].id" # 把返回的 ID 存到上下文
17
18 # 第二步:用上一步的 ID 更新商品
19 - name: update-item
20 url: https://api.example.com/items/[CONTEXT].itemId
21 method: PUT
22 body: '{"price": "24.99"}'
23 conditions:
24 - "[STATUS] == 200"
25
26 # 第三步:验证价格更新
27 - name: get-item
28 url: https://api.example.com/items/[CONTEXT].itemId
29 conditions:
30 - "[STATUS] == 200"
31 - "[BODY].price == 24.99"
32
33 # 第四步:清理(即使前面失败也执行)
34 - name: delete-item
35 url: https://api.example.com/items/[CONTEXT].itemId
36 method: DELETE
37 always-run: true
38 conditions:
39 - "[STATUS] == 204"
这种能力让你可以监控完整的业务流程——登录 → 操作 → 登出,或者创建 → 更新 → 验证 → 删除。比单纯的端点检查强太多了。
外部端点:把 Gatus 当状态面板用
如果你的服务在内网,Gatus 探测不到怎么办?External Endpoints 允许你的 Agent 主动推送状态到 Gatus:
1external-endpoints:
2 - name: ext-ep-test
3 group: core
4 token: "potato"
5 heartbeat:
6 interval: 30m # 30 分钟没收到推送就告警
7 alerts:
8 - type: discord
9 description: "healthcheck failed"
10 send-on-resolved: true
你的 Agent 只需发一个 HTTP 请求:
1POST /api/v1/endpoints/core_ext-ep-test/external?success=true&error=&duration=10s
2Authorization: Bearer potato
还支持心跳检测——如果你的 Agent 挂了不再推送,Gatus 也会告警。
40+ 告警通道
这是 Gatus 最让人省心的地方。告警通道的配置是全局的,每个端点可以单独绑定:
支持的告警通道包括:Slack、Discord、Telegram、Teams Workflow、PagerDuty、Twilio、Email(SES/SendGrid/SMTP)、Google Chat、Matrix、Mattermost、Opsgenie、Splunk、Datadog、New Relic、ntfy、Signal、Line、Zulip、GitHub/GitLab/Gitea Issues、ClickUp、Incident.io、n8n、Zapier 等等。甚至支持自定义 Webhook。
告警还支持设置阈值——比如连续失败 3 次才触发,以及恢复时自动发送通知:
1endpoints:
2 - name: my-api
3 url: "https://api.example.com/health"
4 alerts:
5 - type: slack
6 description: "API 健康检查失败"
7 failure-threshold: 3
8 success-threshold: 2
9 send-on-resolved: true
SSH 隧道:监控内网服务
Gatus 支持 SSH 隧道,可以从跳板机监控内网服务:
1tunneling:
2 production:
3 type: SSH
4 host: "jumphost.example.com"
5 username: "monitoring"
6 private-key: |
7 -----BEGIN RSA PRIVATE KEY-----
8 ...
9 -----END RSA PRIVATE KEY-----
10
11endpoints:
12 - name: "internal-api"
13 url: "http://internal-api.example.com:8080/health"
14 client:
15 tunnel: "production"
16 conditions:
17 - "[STATUS] == 200"
这个功能对于监控 Kubernetes 集群内部服务或者私有云环境特别有用。
Badges:把状态嵌到任何地方
Gatus 可以生成 SVG 格式的状态徽章,你可以嵌到 GitHub README、文档站点或者任何支持 Markdown 的地方:
1
2
支持四种时间维度的可用性徽章(1h/24h/7d/30d),以及响应时间徽章。
Prometheus 指标
Gatus 可以在 /metrics 端点暴露 Prometheus 格式的指标,包括:
gatus_results_total— 每个端点的检查总数gatus_results_duration_seconds— 请求耗时gatus_results_certificate_expiration_seconds— 证书过期倒计时gatus_results_endpoint_success— 端点成功/失败状态
你还可以给端点添加自定义标签来分组:
1endpoints:
2 - name: front-end
3 group: core
4 url: "https://twin.sh/health"
5 extra-labels:
6 environment: staging
7 team: platform
存储选项
Gatus 支持三种存储方式:
| 类型 | 说明 | 适用场景 |
|---|---|---|
memory |
默认,数据存在内存中 | 快速体验,重启后数据丢失 |
sqlite |
SQLite 数据库文件 | 单机部署,轻量持久化 |
postgres |
PostgreSQL 数据库 | 生产环境,高可用 |
对于生产环境,推荐 PostgreSQL + caching,对于小团队或者个人项目,SQLite 就够了。
部署方式
Docker
1docker run -p 8080:8080 \
2 --mount type=bind,source="$(pwd)"/config.yaml,target=/config/config.yaml \
3 --name gatus ghcr.io/twin/gatus:stable
Kubernetes(Helm)
1helm repo add twin https://twin.github.io/helm-charts
2helm repo update
3helm install gatus twin/gatus
二进制安装
1go install github.com/TwiN/gatus/v5@latest
配置文件默认在 config/config.yaml,可以通过 GATUS_CONFIG_PATH 环境变量自定义路径。如果指向一个目录,所有 *.yaml 和 *.yml 文件会被自动合并——这意味着你可以把不同团队、不同服务的配置放在不同文件里,统一管理。
Go 实现的亮点
作为一个 Go 项目,Gatus 有几个值得注意的实现细节:
低资源消耗。这是 Go 应用的天然优势。Gatus 在生产环境中内存占用通常在几十 MB 级别,CPU 使用率极低。对于同时监控几十个甚至上百个端点的场景,完全不在话下。
并发控制。Gatus 使用 goroutine 来并发执行健康检查,但通过信号量控制最大并发数(默认 3)。这避免了大量端点同时检查导致的资源争抢,确保响应时间测量的准确性。
配置热加载。修改配置文件后,Gatus 会自动重新加载,不需要重启服务。skip-invalid-config-update 选项可以防止错误配置导致服务中断。
连通性检测。Gatus 可以配置连通性检查器,当它自己断网时暂停所有检查,避免误报。
安全特性。支持 Basic Auth、OIDC 认证、TLS 加密、mTLS 客户端证书、OAuth2 Token 获取。端点 URL 中的敏感信息可以在 UI 中隐藏。
一个完整的配置示例
1ui:
2 title: "服务平台状态监控"
3 header: "MyCompany"
4 dark-mode: true
5 buttons:
6 - name: "文档"
7 link: "https://docs.example.com"
8
9storage:
10 type: postgres
11 path: "postgres://gatus:password@db:5432/gatus?sslmode=disable"
12 caching: true
13
14alerting:
15 discord:
16 webhook-url: "https://discord.com/api/webhooks/xxx"
17 slack:
18 webhook-url: "https://hooks.slack.com/services/xxx"
19
20connectivity:
21 checker:
22 target: 1.1.1.1
23 interval: 1m
24
25endpoints:
26 - name: frontend
27 group: core
28 url: "https://example.com"
29 interval: 5m
30 conditions:
31 - "[STATUS] == 200"
32 - "[RESPONSE_TIME] < 500"
33 - "[CERTIFICATE_EXPIRATION] > 48h"
34 alerts:
35 - type: slack
36 failure-threshold: 3
37 send-on-resolved: true
38
39 - name: api-server
40 group: core
41 url: "https://api.example.com/health"
42 interval: 1m
43 client:
44 oauth2:
45 token-url: https://auth.example.com/token
46 client-id: xxx
47 client-secret: yyy
48 scopes: ['api.read']
49 conditions:
50 - "[STATUS] == 200"
51 - "[BODY].status == healthy"
52 alerts:
53 - type: discord
54 failure-threshold: 2
55 send-on-resolved: true
56
57 - name: database-tcp
58 group: infrastructure
59 url: "tcp://db.internal:5432"
60 interval: 30s
61 conditions:
62 - "[CONNECTED] == true"
和同类工具对比
| 特性 | Gatus | Uptime Kuma | Healthchecks.io |
|---|---|---|---|
| 语言 | Go | Node.js | Python |
| 协议支持 | HTTP/TCP/ICMP/DNS/SSH/gRPC/WS | HTTP/TCP/DNS/Push | HTTP/Push |
| 告警通道 | 40+ | 20+ | 10+ |
| 条件语法 | 丰富(JSONPath/正则/函数) | 简单(状态码/关键词) | 简单 |
| Suite 工作流 | 支持(Alpha) | 不支持 | 不支持 |
| SSH 隧道 | 支持 | 不支持 | 不支持 |
| 存储 | Memory/SQLite/Postgres | SQLite | PostgreSQL |
| 资源占用 | 极低 | 中等 | 中等 |
| 部署复杂度 | 单二进制/Docker | Docker/Node.js | Django + PostgreSQL |
Gatus 的优势在于 条件语法的灵活性 和 协议支持的全面性。Uptime Kuma 在 UI 美观度上更好一些,但 Gatus 在功能性上更强,特别是 Suite 工作流和 SSH 隧道。
适合谁用
- 小团队/个人开发者:需要一个简单但强大的状态监控页,SQLite 模式 + 几个告警通道就够了
- 中大型团队:需要统一管理几十上百个微服务的健康状态,PostgreSQL 持久化 + Prometheus 指标
- SaaS 产品:需要一个面向用户的状态页面,配合 Badges 和 Announcements 功能
- DevOps 工程师:需要主动探测 + 多通道告警,在用户感知问题之前介入
总结
Gatus 的设计哲学很明确:主动探测,先于用户发现问题。它不试图替代 Prometheus 或 Grafana,而是填补了"无流量时也能发现问题"这个空白。
作为 Go 开源项目,Gatus 的代码质量不错,单二进制部署、低资源消耗、配置热加载这些特性都体现了 Go 语言在基础设施工具上的优势。如果你正在为团队寻找一个轻量但功能完备的健康监控方案,Gatus 值得试试。
GitHub 仓库:github.com/TwiN/gatus
本文内容整理自 Go语言中文网公众号文章。
