如何搭建状态页:组件、事件与可用性检查
状态页可以在一个地方告诉你的用户,你的服务是否正常运行。搭建一个状态页,你需要:一份组件清单(网站、API、支付、邮件发送等)、每个组件的当前状态、带时间戳更新的事件、过往事件的历史记录,以及可选的订阅功能,让用户无需主动查看就能获知问题。页面本身很简单,真正重要的决定是它运行在哪里:状态页必须在你的应用宕机时依然可用,因此它不应与所报告的对象共用托管、数据库或部署流水线。
状态页的用途
出现故障时,用户想知道三件事:是不是只有我遇到了问题、你们是否已经知晓、以及何时能修复。状态页无需大量客服工单即可回答这三个问题。长期来看,它还能建立信任:公开可见的事件历史和坦诚的复盘报告,能说明你如何处理问题。
它不是更新日志。新功能应放在更新日志页面中,而故障和维护信息则放在这里。
状态页需要什么
数据
| 数据表 | 关键字段 |
|---|---|
| 组件 | 名称(Web 应用、API、支付、邮件发送)、描述、当前状态、显示顺序、分组 |
| 事件 | 标题、影响程度(轻微、严重、危急)、状态(调查中、已定位、监控中、已解决)、受影响组件、开始时间、解决时间 |
| 事件更新 | 所属事件、内容、当时的状态、发布时间、发布人 |
| 维护窗口 | 标题、受影响组件、计划开始和结束时间、说明信息 |
| 订阅者 | 邮箱、是否已确认、关注的组件、退订令牌 |
组件状态通常是一组固定的简短选项:正常运行、性能下降、部分中断、严重中断、维护中。
页面
- 公开状态页: 顶部的总体横幅(「所有系统运行正常」或当前最严重的状态)、每个组件及其状态、正在进行的事件及其更新、即将进行的维护,以及(若有检查数据)一条 90 天历史状态条。
- 事件详情页: 单个事件的完整更新时间线,并拥有独立的 URL,方便客服人员直接链接。
- 历史记录: 按月列出过往事件。
- 订阅: 邮箱订阅,包含确认步骤以及按组件设置的偏好。
- 管理后台: 创建事件、发布更新、修改组件状态、安排维护。
权限
公众可以查看所有已发布的内容,只有你的团队可以发布信息。如果可能,请让管理后台的登录与主应用的登录系统分开,这样即使认证服务出现故障,你也不会被锁在自己的状态页之外。
关键决策:保持独立
大多数自建状态页都是在这一点上失败的。如果你的状态页:
- 与你的应用运行在同一台服务器或同一托管账户上,
- 读取同一个数据库,
- 位于同一套域名配置或 CDN 配置之后,
- 或由同一条流水线部署,
那么很多故障也会让它一同宕机,而恰恰在人们最需要它的时候。实用的做法是:
- 独立托管。 使用与主应用不同的项目或服务商。
- 使用独立子域名,例如
status.example.com,在 DNS 中单独指向。参见域名与 DNS 的工作原理。 - 独立的数据。 事件数据存放在状态页自己的存储中,而不是你的应用数据库。
- 静态兜底。 一些团队将公开页面做成静态页面,每次更新时重新构建,这样几乎没有可能出问题的环节。
手动更新还是自动检查
手动(建议从这里开始)
团队通过管理后台手动发布事件并修改组件状态。许多状态页在实践中都是这样运作的,因为人工判断(「部分卡类型的支付较慢」)比自动化的红点更有用。
为了尽快发现问题,可以使用外部可用性监控工具,每分钟左右检查一次你的应用,并通过邮件、短信或聊天工具提醒你。许多监控服务都提供免费套餐。
自动化
自动化意味着有程序定期检查每个组件并更新其状态。这需要一段在定时任务中运行的代码,并且从你的主应用基础设施之外发起检查。两种常见模式:
- 外部监控工具通过 webhook 调用你的状态页,在检查失败或恢复时,由状态页更新对应组件。
- 定时任务运行在状态页自己的托管环境中,对每个组件发起探测并记录结果。在依赖它之前,请先确认你的托管服务如何处理定时任务。我们关于运行后台任务的指南介绍了各种选择。
在网络较慢时,自动化的状态变化可能会反复跳动(正常、故障、正常)。在更改状态前,应要求连续两到三次检查失败,并在宣布严重故障之前由人工确认。
撰写事件更新
- 尽早发布。 在几分钟内发出「我们正在调查登录失败的报告」,胜过一小时后才发出一条完美的消息。
- 说明用户能感受到什么,而不是内部出了什么故障。
- 承诺下一次更新的时间,并且确保按时兑现。
- 解决后用简短的总结收尾: 发生了什么、持续了多久、你们正在做出哪些改变。
一个行之有效的首个提示词
为我们的应用 Parcelio 搭建一个独立的状态页,单独托管在 status.parcelio.com。组件包括:网站、追踪 API、通知、支付,每个组件的状态可选为:正常运行、性能下降、部分中断、严重中断或维护中。公开页面显示总体横幅(使用当前最严重的状态)、每个组件及其状态、正在进行的事件及其带时间戳的更新(最新的在前)、即将进行的维护,以及按月列出的过往事件。每个事件都有独立页面。添加一个受密码保护的管理页面,用于创建事件(标题、影响程度、受影响组件)、发布更新(内容和状态:调查中、已定位、监控中、已解决)、修改组件状态以及安排维护。添加一个 POST /api/check-result 接口,接收外部监控工具传来的组件名称和正常/故障信息,并通过密钥令牌保护;只有连续三次故障后才将组件标记为性能下降。所有数据存储在本应用自己的数据库中。设计保持简洁、平静,并能在手机上快速加载。
搭建步骤
- 公开页面,以及可手动发布事件的管理后台。 仅此一步就已是一个可用的状态页。
- 单独托管,并将一个子域名指向它。
- 事件详情页和历史记录。
- 维护窗口。
- 订阅功能。 双重确认的邮件订阅,以及新事件和更新的通知。发送邮件需要邮件服务商,参见如何从你的应用发送邮件。
- 监控 webhook,如果你希望状态自动变化。
- 进行一次演练。 创建一个模拟事件,发布更新,将其解决,检查邮件,然后删除它。
常见错误
- 与应用放在一起托管。 这是最常见也最严重的错误。
- 页面始终显示「所有系统运行正常」。 如果它从不显示问题,用户就会不再信任它。
- 没有时间戳或时区。 时间始终要附带时区显示。
- 管理后台依赖主应用的登录。
- 更新之间长时间沉默。 「暂无变化,仍在处理中」是一条有效的更新。
- 自动状态反复跳动。 在改变状态之前,应要求多次连续失败。
何时选择托管式状态页服务更合适
托管式状态页服务正是为解决独立性问题而设计的:它们运行在独立的基础设施上,通过邮件和短信处理订阅者通知,并且通常包含监控以及与事件管理工具的集成。如果可用性是你向客户收费的一部分,或者你有义务向合同方报告事件,那么专门的服务通常值得投入。许多服务为小团队提供免费或低价套餐,因此在自建之前不妨先了解一下。
在以下情况下可以选择自建:你希望完全掌控设计和文案;需求简单(只有少量组件、手动更新);或者状态页是你为他人构建的产品的一部分。
在 Mythex 上搭建
在 Mythex 上,你可以将状态页作为独立项目搭建,与主应用分开,从而获得独立的托管和自己的数据库。在对话中描述需求,在实时预览中查看效果,然后发布,并连接一个像 status.yourdomain.com 这样的子域名(自定义域名属于 Pro 功能)。请注意,已发布的 Mythex 应用及其数据库在闲置时会休眠,并在下次访问时唤醒,因此长时间无人访问后的首次加载可能较慢;一个简单、轻量的页面会有所帮助。
Mythex 目前没有文档说明定时任务,因此对于自动检查,请使用外部可用性监控工具,调用状态页中的 webhook 端点(参见 webhook 教程)。发送给订阅者的邮件通过你自己的服务商发送,密钥以项目密钥的形式保存(参见发送邮件教程)。
常见问题
什么是状态页?
状态页是一个公开页面,显示你服务的每个部分是否正常运行,列出当前及过去的事件并附带带时间戳的更新,通常还允许用户订阅通知。它能在故障期间减少客服压力。
我的状态页应该和应用托管在一起吗?
不应该。如果它与你的应用共用托管、域名配置或数据库,就可能在它本应报告的同一次故障中一起宕机。请将其单独托管,例如使用 status.yourdomain.com 这样的子域名。
我需要自动化监控吗?
监控有帮助,但起步时并非必需。许多小团队手动发布事件,并使用外部可用性监控工具来提醒自己。自动更改状态可以之后再加。
事件更新应该写什么?
写清楚受到影响的是什么、用户会注意到什么、你正在做什么,以及下一次更新的时间。内容要简短、直白,并带上时间戳,即便只是「仍在调查中」。