食亨在如何维护 SAAS 服务稳定性的每个环节都有着很多自己的思考,使用不同的方向来完成这个目标,通过 “开发 - 监控” 协同,将稳定性从 “被动救火” 升级为 “主动预防”,实现 “预警→定位→修复” 的自动化闭环,而本次内容重点讲解这其中之一:后端业务层监控
一、为什么需要业务监控:从「被动救火」到「主动预防」
(一)SAAS 稳定性的终极挑战
当 SAAS 服务达到「五个九」(99.999%)稳定性后,剩余 0.001% 的故障可能源于业务逻辑隐性缺陷、数据不一致或用户体验断层。传统系统监控(CPU / 内存 / 网络)已无法覆盖这些「业务级暗涌」,必须构建以业务为中心的监控体系。
(二)业务监控的本质定位
区别于基础设施监控,也区别于业务数据的可视化,业务监控聚焦「用户视角的服务质量」和「数据视角的逻辑正确性」,通过技术与业务双维度指标,实现「异常预警→根因定位→及时修复」的全链路闭环,核心在于找出故障,并将故障处理周期从「小时级」压缩至「分钟级」。
(三)核心目标整理
- 业务指标可观测:
-
监控支付成功率(目标>99.9%)。
-
同时段、不同平台订单数比例diff
-
核心资产监控(用户余额、订单、优惠券)
-
by 用户、by 门店、by 品牌的核心指标(短时间内订单支付失败率)
- 异常行为可追踪:
-
核心资产并发导致异常(例:优惠券重复发放)
-
报表导出异常
- 业务数据流可验证:
-
订单数据、对账数据,在不同的库表,最终表现一定符合一个规则
-
活动库存与订单的数量一致性
二、拆分路径:业务的监控的诉求实现
(一)核心诉求拆解:构建敏捷响应的监控生态
1、配置便捷性: 可视化简单易懂、直观的预览「开始-过程-结果」
2、配置灵活性: 可满足不同业务不同场景不同数据源计算复杂的监控诉求,可根据实时业务场景进行变化
3、报警智能化: 报警信息组装灵活,「可分级、可分组,可分群」,可图形化可视化预警趋势。
(二)核心业务实现拆解
1、目标数据从何而来?
-
周期性的执行查询目标数据 sql
-
监听 mq 获取实时数据
-
提供数据收集的接口
2、如何找出问题数据?
一维数据,针对数据本身的校验
-
指标都符合预期(结果集都为 true) 反向带目标问题找问题
-
指标存在一个不符合预期(结果集为存在 false)目标非预期结果问题
暂时无法在飞书文档外展示此内容
二维数据(数据集+时间、结果集+时间)在一维数据的基础上加上时间概念
-
固定时间范围内:例子:12 点范围,即 12:00~13:00
-
动态滑动窗口时间范围内:例子 :1 分钟内,即当前时间戳+当前时间戳1 分钟前的数据
暂时无法在飞书文档外展示此内容
三、核心业务基础实现:监控的生命周期
(一):监控的开始:监控资源的初始与管理
1、线程的初始化
服务的初始,检查数据设置监控规则列表,针对监控任务的规则的状态(暂停、开始、规则二次编辑后的待更新)统一的管理流程,找到有用的任务进行执行,保证任务「热部署」能力。每分钟检查一次,规则修改后无需重启系统
- 任务状态机管理
- 热部署 实现
- 监控任务线程隔离
@Scheduled(cron = "0 * * * * ?")
public void refreshScheduledTasks() {
try {
List<NewMonitorTask> enabledTasks = monitorTaskService.getEnabledTasks();
// 停止已不存在或已禁用的任务
scheduledTasks.forEach((taskId, future) -> {
if (enabledTasks.stream().noneMatch(task -> task.getId().equals(taskId))) {
cancelTask(taskId);
}
});
// 更新或新增任务,已存在任务会二次过滤
for (NewMonitorTask task : enabledTasks) {
scheduleTask(task);
}
} catch (Exception e) {
log.error("Refresh scheduled tasks failed", e);
}
}
2、多策略的数据采集组成
- 定时任务的数据查询
- mq 监听的实时消费
- 提供接口的被动调用
暂时无法在飞书文档外展示此内容
(二):监控的执行:异常校验的分层递进机制
校验目标
根据步骤一得到的目标数据 A,可以校验目标数据 A 本身或者根据数据 A 的信息获取数据 B 等一系列数据集合,来校验 B,或者 A 与 B 之间的关联规则
二次过滤
根据条件进行二次过滤拆分数据组成多个校验规则集合,数据 A 字段 a 满足 1,2 执行策略【一】,数据 A 字段 b 满足 3,4 执行策略【二】
校验策略
一维数据校验规则
暂时无法在飞书文档外展示此内容
二维数据校验规则
暂时无法在飞书文档外展示此内容
(三):监控的结束:预警的机制
1、基础报警能力,报警信息的组合
暂时无法在飞书文档外展示此内容
2、报警数据持久化能力,从「黑盒感知」到「白盒分析」
为什么报警需要持久化的能力?
传统监控往往陷入 "触发报警 - 处理故障" 的单次循环,而忽略了报警数据的沉淀价值。真正的业务监控需要构建「可追溯的感知体系」,对于监控,我们应该是有感知的能力,而不是一个监控的黑盒,同时持久化的不只是校验结果的,更是校验的过程产生的二次数据,通过观察这些数据,结合grafana更能看到出监控指标的趋势。
为什么需要 mq 能力?
业务的指标异常,是无法通过系统指标察觉的,这时如果出现高危报警,某个业务无系统异常,但实际业务完全无法运行,此时通过 mq 可以触发业务熔断开关,实现自动化的安全措施,此时 MQ 能力扮演着「业务异常神经传导」的关键角色。并且此次业务熔断可以根据报警针对性的 by 用户,by品牌进行熔断
3、报警内容模版组装
通过提供报警模块,采用填充的方式进行报警内容的补充,其中{{}}里面的内容替换为具体数据
【{{报警等级}}级】{{活动名称}}(任务Id:{{监控任务 id}})
▸ 错误类型:{{监控类型}}
▸ 活动配置:库存{{数据A.库存字段}}件,当前订单量{{数据A.订单字段}}笔
▸ 异常信息:
├─ 异常业务存在服务:营销服务
├─ 异常业务存在方法:营销服务.优惠券接口#sendCoupons
└─ 触发报警异常数据:订单号:{{数据详细信息}},金额:{{数据详细信息}},时间 {{数据详细信息}}
└─ 活动信息:活动 Id:{{数据详细信息}},活动名称:{{数据详细信息}},活动{{数据详细信息}}
└─ 数据库信息:{{数据详细信息}}
▸ 建议动作:
1. 检查 redis 锁逻辑是否生效,检查 redis 数据的库存是否正确
2. 紧急补充措施:执行库存SQL:UPDATE stock SET real_num=real_num+203 WHERE id= {{id}},并刷新缓存
▸ 相关人员:{{人员 1}},{{人员 1}}
四、简单易读的可视化规则配置:让监控规则从代码走向业务
在业务监控体系里,可视化规则配置是打破技术与业务壁垒的关键桥梁。我们通过「配置可视化 - 过程透明化 - 结果可解释」的三层设计,让业务人员能自主定义监控规则,技术人员可快速定位配置问题,实现从 "开发配置" 到 "业务自运维" 的跨越。
1、画布式配置界面:像搭积木一样定义监控规则
可视化配置三原则:
-
零代码门槛:采用拖放式组件库,业务人员通过拖拽「数据源组件」「校验规则组件」「报警组件」即可完成规则定义
-
实时预览:配置过程中实时显示规则执行模拟结果,避免配置错误
-
版本追溯:自动记录配置变更历史,支持一键回滚至任意版本
暂时无法在飞书文档外展示此内容
配置案例:业务人员通过拖拽「订单库数据源」「订单表采集数据组件」「支付状态字段」「成功率计算组件」「 阈值组件」「P1 级报警组件」,5 分钟内完成配置。系统实时预览显示 "近 10 分钟内支付成功率 99.92%",确认无误后发布规则。这种配置方式使新监控规则的上线时间从传统开发的 2 小时缩短至 10 分钟。
2、校验逻辑可视化:从黑盒计算到白盒追踪
规则执行过程透明化:
-
条件表达式可视化:将复杂的校验逻辑(如
(success_rate < 99.9% && order_num > 1000)
)转化为数据流的形式 -
中间结果展示:实时显示校验过程中计算表达式计算出来的中间值(如支付成功数、总订单数、计算出的成功率)
-
历史执行记录:保存近 10 条的规则执行日志
暂时无法在飞书文档外展示此内容
3、报警链路可视化:让通知流程有迹可循
报警链路五要素展示:
-
触发条件:清晰显示报警触发的具体规则(如 "支付成功率连续 3 次<99.9%")
-
通知对象:可视化展示报警将发送给哪些人(如研发组张三、运维组李四)、通过什么渠道(电话 / 短信)
-
响应时效:标注各等级报警的预期响应时间(如 P0 级需 1 分钟内响应)
-
历史记录:记录该报警规则的所有触发历史,包括处理人、处理时间、处理结果
-
演练入口:提供 "模拟报警" 功能,测试报警链路是否畅通
五、复杂规则的场景的满足:从标准化监控到定制化防御体系
1、多数据源融合:编织立体化监控网络
异构 数据源 统一接入框架实现跨系统数据关联监控,解决传统单数据源监控的盲区问题,整个监控任务过程中,即可以统一使用一个数据源、也支持每个数据获取独立数据源
数据源类型 | 接入实例 | 适用场景 |
---|---|---|
关系型数据库 | MySQL/OB | 基础数据查询 |
非关系型数据库 | MongoDB/Redis | 缓存数据对比数据库 |
MQ 消息队列 | Kafka/RocketMQ | 实时业务消息的异常检测/业务行为检测 |
第三方 API | http连接 | 第三方接口的响应监控 |
前端埋点 | sdk 上报 | 用户数据行为分析 |
2、数据二次过滤:精准锁定数据子集、二次分流
在复杂的场景中,一个监控任务可能存在多个不同场景下的监控规则,所以在每个环节支持二次过滤,来精准控制数据范围来实现
暂时无法在飞书文档外展示此内容
3、数据二次运算:构建多层级校验逻辑
支持从简单数值比对到复杂业务规则的全场景覆盖:支持对任意数据源进行二次计算与组合运算,并提供基础选算
暂时无法在飞书文档外展示此内容
4、全量表达式支持:覆盖所有业务常见判断场景
类型 | 支持表达式 |
---|---|
基础比较 | =、>、<、>=、<=、!= |
集合运算 | IN、NOT IN |
空值判断 | IS NULL、IS NOT NULL |
模糊匹配 | LIKE、NOT LIKE |
逻辑运算 | AND、OR |
六、灵活组装的报警规则:构建精准触达的响应体系
1、分级响应:让报警时效与风险等级精准匹配
报警分级不是简单的标签分类,而是基于故障影响半径的数学建模。我们通过「业务损失速率 × 修复复杂度」公式定义三级响应体系,每个级别对应差异化的报警规模与触达策略:
报警等级 | 判定标准 | 响应时效 | 报警组合 | 典型场景 |
---|---|---|---|---|
紧急(P0) | 核心业务中断 / 资损风险>1000 元 / 分钟 | 1 分钟 | 电话+短信+邮箱+群消息 | 支付链路成功率<99%、核心资产数据不一致 |
重要(P1) | 非核心业务异常 / 资损风险<1000 元 / 小时 | 2 小时 | 短信+邮箱+群消息 | 单平台外卖接单时间低于历史平均值 |
警告(P2) | 潜在风险 / 性能退化 | 2 天 | 邮箱+群消息 | by用户出现短时间支付失败场景 |
2. 人群画像:让报警内容与角色诉求深度耦合
报警信息的本质是「故障翻译」—— 为研发提供「技术诊断书」,为运营生成「业务处置单」。通过建立角色专属的信息过滤模型,实现报警内容的智能裁剪:
▶ 研发视角:技术细节与根因线索的全集
【P0级】活动库存校验异常(任务Id:12)
▸ 错误类型:库存扣减异常
▸ 活动配置:库存1000件,当前订单量1203笔
▸ 异常信息:
├─ 异常业务存在服务:营销服务
├─ 异常业务存在方法:营销服务.优惠券接口#sendCoupons
└─ 触发报警异常数据:订单号:XXX,金额:XX,时间 XXXX.XX.XX
└─ 活动信息:活动 Id:XX,活动名称:XX,活动XXX
└─ 数据库信息:xxx.xx
▸ 建议动作:
1. 检查 redis 锁逻辑是否生效,检查 redis 数据的库存是否正确
2. 紧急补偿措施:执行库存SQL:UPDATE stock SET real_num=real_num+203 WHERE id=xxx,并刷新缓存
▸ 相关人员:@A名称、@B 名称
这种「异常现象 + 技术指标 + 修复线索」的三段式结构,让研发可直接根据报警内容定位到代码第 XXX 行的类,并对异常场景有一个基本认知。
▶ 运营视角:业务影响与处置流程的极简呈现
【P0级】品牌XX活动库存异常
▸ 业务影响:已产生203笔超库存订单(客单价89元)
▸ 处置步骤:
① 立即关闭活动入口(操作路径:后台→营销→活动管理→作废)
② 同步客户:话术「因活动火爆活动库存业务临时调整,您的活动A已达库存上限,先进行关闭处理」
▸ 研发进展:已定位锁服务故障,预计15分钟内修复,请保持联系,时刻等待最新消息
▸ 运营人员关注:@A名称、@B 名称
通过隐去 Redis 锁失效等技术细节,聚焦「关活动 - 补客户 - 同步话术」的运营动作,在实时故障中实现「5 分钟内活动止损 + 2 小时客户安抚」的高效处置。
通过将报警规则从「统一通知」升级为「精准服务」,实现了从 "报警风暴" 到 "决策支持" 的质变。真正释放了研发团队的生产力。
七、结语:穿越稳定性的 "死亡谷",构建业务监控的标准范式
本文重点介绍食亨在业务监控的经历路程,由浅入深的从「需求分析 - 基础实现 - 高阶实战」的方式来讲解了在 SAAS 服务中业务监控的完整实现链路。当 SAAS 服务叩开 99.999% 稳定性的大门,那剩余的 0.001% 不再是简单的技术问题,而是对业务本质的深度解构与重构。唯有将技术监控的 "显微镜" 与业务洞察的 "望远镜" 结合,才能穿越稳定性的 "死亡谷"。