文档

监控项

监控项就是你想要盯住的一样东西,外加判断它是否健康的规则。一共有三十种。其中大多数会从我们的网络发出请求并判断响应;另有两种则等待某些内容从你那边发过来;还有四种收集你的路由器导出到你自己私有探针上的流量数据。

各个类型

Web 与网络

类型检查什么
http某个 URL 是否响应,包括状态码、响应时间,以及可选的、必须出现在响应正文中的一段文本。
ping某台主机是否响应 ICMP。
tcp某个端口是否接受连接。
udp发出的数据报是否收到回复。
dns某个域名是否能解析,并可选地校验解析结果是否为你期望的记录。

证书与域名

类型检查什么
ssl_cert证书还剩多久到期,以及证书链是否有效。
tls_audit九次握手:每个 TLS 版本、各个弱加密套件族、密钥长度,以及安全响应头。我们无法执行的探测会报告为未测试,而不是算作通过——详见下文。
domain_expiry域名注册还剩多久到期。
blacklist某个地址或域名是否出现在主流封禁名单上。

邮件

类型检查什么
smtp, imap, pop3服务器是否能用自己的协议完成一次真实的会话,并协商 STARTTLS。它从不进行身份验证:要验证登录,就意味着为每个监控项保存一份可用的邮箱密码。
mail_posture其他人能否信任该域名发出的邮件——SPF、DKIM、DMARC。

基础设施协议

它们之所以存在,是因为对端口做一次 tcp 检查,几乎说明不了它们的任何情况。SMSC 在不再为任何人完成 bind 之后,仍会长时间接受 TCP 连接;SIP 协议栈可能在套接字保持打开的状态下卡死;证书已过期的 XMPP 服务器照样能完成 TCP 握手。

类型检查什么
snmp轮询一组 OID,并逐个与阈值比较,每项检查都有各自的严重级别。
smpp完成 bind 与 unbind。它从不提交短信。
sip发送 OPTIONS。非 2xx 的最终响应算作降级,而不是宕机:代理对陌生来源回复 405,说明它工作正常,只是拒绝了我们。
xmpp打开一个流并协商 STARTTLS。
grpc调用 grpc.health.v1.Health/Check。gRPC 把状态放在 HTTP/2 trailer 里,因此失败的调用照样回应 200 OK——这正是 http 监控无法替代它的原因。Pro 及以上套餐。

数据库

Pro 及以上。对 5432 端口做 tcp 检查只能证明有东西接受了连接, 而数据库每一种值得关心的故障都会让套接字继续开着:处于崩溃恢复中的 Postgres、被泄漏连接的 应用占满的连接上限、密码已过期的角色、被改名的数据库、没有挂载上的数据目录。所以这些检查 会建立连接、完成登录,并向服务器问一个最简单的问题。

类型检查什么
postgres连接、认证并执行 select version()。数据库名为必填,因为 Postgres 不存在不指定数据库就能连接的情况。
mysql同上,并涵盖 MariaDB——同一套通信协议,而不是第二种检查。
redis连接、认证并发送 PING。仍在载入数据的副本会回应 -LOADING,这会作为独立的原因上报,而不是超时。
mongodb连接、认证并执行 ping 命令。支持 mongodb+srv 地址,这也是访问托管 MongoDB 的常用方式。
mssql通过 TDS 连接、登录并执行 select @@version

它们都不读取也不写入任何数据。这是可用性检查,不是合成事务:请给它一个 除连接之外什么都做不了的账号。

凭据以明文存储,因为执行检查的探针会原样收到该配置。因此这五种只会在获准处理个人数据的 探针上运行,这与 snmpsmpp 的限制相同。

这意味着两种位置之一。你自己的私有探针,这也是这些检查的设计目标:它运行 在你自己网络内的硬件上,配置因此从不离开你的基础设施;而且它通常是唯一能够访问到值得监控的 数据库的东西——位于 VPC、专线或白名单之后的数据库,对任何外部网络(包括我们的网络)都是 不可达的。否则就是我们自己在欧盟的观测点,用于确实可公开访问的数据库。

容器

Pro 及以上。检查容器发布的端口,回答的是它前面的代理。在重启策略之下反复崩溃的容器每次只在线几秒,失败的 HEALTHCHECK 不会关闭端口,因内存耗尽被杀后又重启,看起来只像一次慢请求。这三件事 Docker 引擎都知道。

类型检查内容
docker按名称或 ID 向引擎查询一个容器。运行中即为正常;HEALTHCHECK 不健康,或容器已暂停、已退出、因内存耗尽被杀,即为宕机;健康检查仍在启动中,或重启策略在最近五分钟内重启过它,即为降级。它从不启动、停止或运行任何东西。

能访问引擎 API 就等于拥有那台主机的 root 权限,所以端点及其客户端证书都是凭据,这一类型只在获准处理个人数据的探针上运行。只有以 DOCKER_SOCKET_ENABLED=true 启动的探针才会打开 unix 套接字——这是你在自己引擎旁边的私有探针上设置的,我们的探针从不设置;在其他任何地方,检查都会弃权,而不是把你的容器报告为宕机。带客户端证书的 tcp://https:// 端点在两者上都可用。

网络流量

Business 及以上套餐。可用性检查能告诉你链路有响应;它无法告诉你链路已经饱和、某个备份任务在中午把它塞满,或者流向你 Web 层的流量悄无声息地降到了零。你的路由器和交换机本来就在统计这些,并且可以导出。这些类型收集这份导出,把它变成速率、按协议的分布,以及最繁忙的端口和地址。

类型检查什么
netflow来自路由器的 NetFlow v5 和 v9,UDP 2055 端口。模板随到随学;早于其模板到达的记录会被计数并丢弃,绝不靠猜。
jflow来自 Juniper 路由器的 J-Flow,线路上就是 NetFlow,使用同一端口。
ipfixIPFIX,接替 NetFlow v9 的 IETF 标准,UDP 4739 端口——包括可变长度字段和厂商专有字段。
sflow来自交换机的 sFlow v5,UDP 6343 端口:抽样的数据包头部,穿过 VLAN 标签解析到 IPv4 或 IPv6,并按交换机报告的抽样率换算回来。

每个阈值都是可选的——最大比特率、最小比特率、最大包速率。高于或低于其中之一即为降级。都不设置时,监控项只记录并绘制流量图表,不会因数值告警。导出器停止发送的时间超过你允许的上限即为宕机;发送了错误协议的导出器——把 sFlow 发给 NetFlow 监控项——同样宕机,并附有说明原因的消息。

这些类型只在你自己的私有探针上运行。流量导出走 UDP,不带任何认证:放在我们共享网络上的采集器只能信任发送方地址,而任何人都能伪造或冒领这个地址。放在你网络内部的探针,只有你自己的路由器能访问到。你的流量记录也留在你那边——它们包含你网络中人员的地址,所以探针在记录到达的地方完成汇总,只把速率和前十排行表发给我们。用 FLOW_COLLECTOR_ENABLED=true 启动探针,发布 UDP 端口,把路由器指向它,并在创建监控项时选择这个探针。

主动向我们上报的东西

类型检查什么
heartbeatcron 任务或批处理作业在结束时调用一个 URL。超过间隔仍然没有动静,就是失败。把它用在别的手段都看不到的地方——每夜的备份、每小时的导入。
server_agent运行在你自己机器上的小型代理程序,上报 CPU、内存和磁盘。用监控项页面上的链接通过 curl 自行获取它。

多久运行一次

间隔由你选择,下限由你的套餐决定。Free 每分钟检查一次,Starter 每 45 秒,Pro 每 30 秒,Business 每 15 秒,Enterprise 每 5 秒。

有四种类型无论什么套餐都有自己的下限,因为它们的答案不会一分钟一变,问得更勤只会带来噪声,并给别人的服务器增加负担:

类型最快检查频率
blacklist每小时
ssl_cert每六小时
domain_expiry, mail_posture, tls_audit每天两次

间隔并不等于你多快得知故障

这一段值得读两遍。单次检查失败并不会开启事件。监控项必须连续失败三次——这就是 confirmations 设置,默认值为三——之后才会有人收到通知。

不过,那并不等于三倍的间隔。某次检查失败时,下一次检查会被提前,而不是等满整个间隔,所以一个五分钟的监控项确认故障所需的时间远不到十五分钟。一条结果只能让下一次检查提前,绝不会让它推迟。

如果你宁愿被早点叫醒、偶尔白跑一趟,就把 confirmations 调低。对于你明知会抖动的目标,则把它调高。

检查在多个位置之间轮换

我们从多个地点发起检查,每个间隔用一个,依次轮换。一个五分钟的监控项配三个观察点,意味着每个观察点每十五分钟看它一次,而监控项本身仍然每五分钟被检查一次。

这正是确认机制有意义的原因:连续三次失败,是从三个不同地点看到的三次失败,因此某个探针单纯访问不到你的服务器并无大碍——下一个区域会成功,连续失败的计数随之清零。

一处失败而另一处正常,属于降级,而不是宕机。宕机应当意味着你的站点无法访问,而不是某一个观察点看不到它。它仍然计为失败,事件依然会开启,严重级别为降级。

防火墙不是故障

在某个地点被封禁的站点,会让来自那里的每一次检查都失败,而在其他地方一切照常。把这算作停机时间,会让你的可用性数字变成关于我们路由的说明,而不是关于你的服务。

因此,从未访问到某个监控项的区域,在三次失败之后会被从该监控项中排除。而曾经能访问、如今访问不到的区域则会永久继续计入——因为从那里看这是真实的故障,掩盖它只会更糟。

如果是站点周围的世界变了——政府封锁、路由消失、后来加上的地域限制——你可以在监控项页面上对它重新校准。这会清除该监控项下所有区域的历史,于是当前行为成为新的基线。它按监控项生效,而且是有意为之,因为仅凭测量无法区分永久封锁与永久故障。

检查在哪里运行,以及我们往那里发送什么

有些观察点位于欧洲经济区之外。配置中可能包含个人数据的检查——带请求头、带请求体的检查——只会从欧洲经济区内部运行。这一点由调度器强制执行,而不是靠制度约束,并且每次构建都会针对真实数据库进行测试。snmpsmpp 以及五种数据库检查同样受到限制,因为在它们当中,凭据本身就是协议。

未测试不等于通过

tls_audit 来说,每项探测有三种结果而不是两种:支持、拒绝,或未测试。Node 的 OpenSSL 3 既没有编译进 RC4 也没有编译进 3DES,所以这两个套件族永远无法从我们的机群发出——而在这些条目下保持沉默,会被读作「我们查过了,它们已经关闭」,这恰恰是在 TLS 审计最常被用来排查的发现项上给出虚假的安全结论。

依赖关系

告诉一个监控项它依赖什么——数据库、网关、上游 API——这样当依赖宕机时,它后面的那些监控项会被标记为连带影响,而不是各自开启事件。只有一个事件,而不是四十个,并且页面指出的是根因而非症状。

维护窗口

安排一个维护窗口,只要它是打开的,就不会呼叫任何人。用它来应对你明知会让服务下线的发布。默认情况下检查照常运行、照常记录,因此这些分钟与其他时间一样计入可用性数字——窗口去掉的是告警,而不是历史记录。关掉「继续检查」,窗口打开期间就不做任何检查,历史记录中留下的是一段空白,而不是一次下滑。维护窗口可以按天、按周或按月重复,而且每一次发生都会拦下告警,不只是第一次。

暂停

已暂停的监控项不会被检查,也不会计入任何统计。它会保留历史记录,所以暂停再恢复不会丢失数据。