Skip to content

值班排班(On-call):现状调研与路线建议 ​

结论先行:上游 Keep 完全没有值班排班能力(无数据模型、无界面、无升级策略),这是更夫与 FlashDuty 的核心差距项,也是国内用户从"告警通知"走向"告警响应"的必经一步。 建议以「轻量排班 + 工作流动态解析」切入,不追求一步到位的完整 On-call 平台。

一、现状盘点 ​

更夫(含上游 Keep)现有能力:

  • 通知渠道:钉钉(@手机号)、企业微信(@手机号)、飞书(@所有人/按邮箱)——均已就绪
  • 排班能力:无。没有班次模型、没有值班人解析、没有升级策略
  • 相关仅有:grafana_oncall provider(对接外部 Grafana OnCall 系统,非自身能力)

FlashDuty / 睿象云对标能力(商业产品验证过的需求集):

  1. 排班表:日/周轮换、自定义周期、多组轮转、时区
  2. 升级策略(Escalation):超时未响应逐级通知备份值班人
  3. 响应确认(Ack):通知带确认入口,谁响应了有记录
  4. 值班表 × 告警路由:按班次自动路由"通知谁"
  5. 调班与假期

二、路线建议(三阶段) ​

P1:轻量排班 + 工作流动态解析(建议先做) ​

设计原则:不做完整 On-call 平台,先解决"通知该发给谁"这一个最高频问题。

  • 新增数据模型:schedule(值班组)+ schedule_rotation(轮换规则:日/周轮换、成员列表、时区)
  • 工作流内新增解析函数:{{ oncall.resolve("支付值班") }} → 返回当前值班人的手机号/邮箱
  • 三件套 provider 无需改动,工作流里直接消费:
yaml
actions:
  - name: notify-dingtalk
    provider:
      type: dingtalk
      with:
        at_mobiles: "{{ oncall.mobiles('支付值班') }}"
  • 管理入口:设置页新增「值班管理」Tab(本期纯表单,不做日历可视化)

为什么这样切入:值班表的本质是"把一组人按时间规则解析成一个收件人列表", 我们的 provider 通知参数已经全部就位,只缺这一层解析。工作量可控(模型 + 解析器 + 表单), 价值直接(告别手工维护值班手机号)。

P2:Ack 确认与升级策略(已落地,设计借鉴 FlashDuty) ​

参照 FlashDuty 升级规则 吸收的设计:

  • 升级触发双条件:「未关闭」/「未关闭且未认领」——采用后者为默认(有人认领即不升级)
  • MTTA 度量:认领记录天然携带 created_at/acked_at,可算"从触发到有人接手"的时长(P3 统计消费)
  • IM 内完成认领:通知消息附认领链接,值班人手机点开即认领(免登录,token 即凭证)

落地形态(引擎零改动,纯函数 + 记录 + 模板编排):

  • ackrecord 记录:通知发出前经 keep.oncall_ack_link(值班组, 告警名) 创建,返回认领链接
  • 免登录认领页 /ack/{token}:手机浏览器点开一键认领
  • 升级检查:keep.oncall_claimed(值班组, 分钟数) 供 interval 工作流判断超时未认领 → @ 全组
  • 内置模板:更夫 · 值班告警钉钉通知(含认领)+ 更夫 · 值班升级钉钉通知

后续增强:认领页直接转派他人、多级升级策略(一线→二线→主管)、重复通知间隔配置

P3:值班可视化与调班 ​

  • 排班日历视图、假期/调班、多班组轮转叠加
  • 与告警路由策略(Alert Routing)联动,按班次自动路由不同通知渠道

三、竞品参照 ​

  • FlashDuty(快猫星云):排班/Escalation 是其两大核心卖点,SaaS 定价按席位——证明该能力独立付费成立
  • Grafana OnCall:开源但依赖 Grafana 生态,国内使用门槛高——可参考其轮换规则模型
  • PagerDuty:Escalation Policy 是经典设计(一级超时 N 分钟 → 二级),语义可借鉴

四、不建议做的 ​

  • 不做完整 On-call SaaS(IM 集成、工单、通话语音外呼)——语音外呼在国内涉及号码资质,且远离更夫核心
  • 不做与 Grafana OnCall 的深度双向集成——更夫自建轻量排班后,该 provider 保留给存量用户即可

基于 MIT 协议开源的 Keep · 由更夫社区维护