【SkyWalking从入门到精通】第22篇:SkyWalking告警配置实战——让你的系统学会“喊救命“

📅 2026/7/9 0:06:24 👁️ 阅读次数 📝 编程学习
【SkyWalking从入门到精通】第22篇:SkyWalking告警配置实战——让你的系统学会“喊救命“

上一篇【第21篇】用SkyWalking排查慢服务——从蛛丝马迹到真相大白
下一篇【第23篇】SkyWalking与单体应用——老系统也能焕发新活力


1. 引言:告警是系统的"痛觉神经"

想象一下,你正在海边度假,脚踩沙滩手捧椰子,突然手机收到一条短信:“订单服务P99响应时间超过5秒,请速处理”——你打开运维群,发现大家已经根据告警信息定位到了问题,正在热火朝天地修复。你想登录VPN帮忙,同事回复:“不用,正在切流量,你继续度假。”

这才是现代运维的理想状态:不是人找问题,而是问题找人

SkyWalking的告警系统就是系统的"痛觉神经"——哪里出了问题,它能第一时间感知并通知你。上篇文章我们学会了排查慢服务,这篇文章我们聊聊如何让系统学会"主动喊救命"。

2. 告警系统的整体架构

+------------------------------------------------------------------+ | SkyWalking 告警系统架构 | +------------------------------------------------------------------+ | | | ① 指标采集层 | | ┌──────────────────────────────────────────┐ | | │ Agent → OAP Receiver → Metrics Aggregation│ | | │ (每秒采集 → 分钟聚合 → 持久化到存储) │ | | └──────────────────┬───────────────────────┘ | | │ | | ▼ | | ② 告警引擎层 | | ┌──────────────────────────────────────────┐ | | │ Alarm Core 每10秒轮询一次指标 │ | | │ ┌────────────────────────────────────┐ │ | | │ │ 匹配告警规则 → 检查触发条件 │ │ | | │ │ → 累加触发次数 → 满足阈值则告警 │ │ | | │ └────────────────────────────────────┘ │ | | └──────────────────┬───────────────────────┘ | | │ | | ▼ | | ③ 通知分发层 | | ┌──────────────────────────────────────────┐ | | │ Webhook | DingTalk | WeChat | Slack | ... │ | | └──────────────────────────────────────────┘ | | │ | | ▼ | | ④ 用户接收 | | ┌──────────────────────────────────────────┐ | | │ 运维人员 → 收到通知 → 查阅SkyWalking UI │ | | │ → 定位问题 → 修复确认 │ | | └──────────────────────────────────────────┘ | +------------------------------------------------------------------+

3. alarm-settings.yml 配置详解

3.1 文件位置与加载方式

告警配置文件通常位于OAP Server的config/alarm-settings.yml。在Kubernetes环境中,这通常通过ConfigMap挂载:

# k8s configmap 示例apiVersion:v1kind:ConfigMapmetadata:name:skywalking-oap-alarm-confignamespace:monitoringdata:alarm-settings.yml:|rules: # 告警规则定义在这里 webhooks: # 通知渠道配置 # ... 其余配置

3.2 告警规则的基本语法

一条告警规则由7个核心字段组成:

rules:# 规则名称(唯一标识)service_resp_time_rule:# 指标名称(来自OAL脚本的定义)metrics-name:service_resp_time# 比较操作符:> >= < <= ==op:">"# 阈值threshold:1000# 统计周期(分钟),表示计算最近N分钟的数据period:10# 触发次数,在period内满足条件count次才真正告警count:3# 静默期(分钟),告警后N分钟内不再重复发送silence-period:5# 告警消息模板message:服务{name}的响应时间超过 1000ms,当前值:{value}ms

这7个字段构成了告警规则的"DNA":

+------------------------------------------------------------------+ | 告警规则字段关系图 | +------------------------------------------------------------------+ | | | metrics-name ──→ 从OAL定义的指标池中选取 | | | | | ▼ | | op + threshold ──→ 定义"什么是异常" | | | | | ▼ | | period + count ──→ 定义"有多异常才算告警" | | | (period内count次超过阈值才触发) | | ▼ | | silence-period ──→ 定义"告警后多久别再烦我" | | | | | ▼ | | message ──→ 定义"告警时告诉我什么" | +------------------------------------------------------------------+

这里有一个新手常踩的坑:period和count的组合决定了告警灵敏度。比如period=10, count=3表示:过去10分钟内,有3次(每10秒一次轮询)超过阈值就告警。如果设为period=3, count=1,告警会非常灵敏,但也容易产生噪音。

4. 内置告警指标详解

4.1 服务级别指标

# 服务平均响应时间service_resp_time:metrics-name:service_resp_timeop:">"threshold:1000period:10count:3silence-period:5message:服务{name}平均响应时间超过1秒# 服务成功率(低于阈值告警)service_sla:metrics-name:service_slaop:"<"threshold:95# 成功率低于95%告警period:10count:2silence-period:5message:服务{name}成功率低于95%,当前值:{value}%# 服务CPM(每分钟调用量)service_cpm:metrics-name:service_cpmop:">"threshold:10000period:10count:2silence-period:10message:服务{name}每分钟调用量超过10000

4.2 端点级别指标

# 端点平均响应时间endpoint_avg_rule:metrics-name:endpoint_avgop:">"threshold:2000period:10count:2silence-period:5message:端点{name}平均响应时间超过2s# 端点成功率endpoint_sla_rule:metrics-name:endpoint_slaop:"<"threshold:90period:10count:2silence-period:5message:端点{name}成功率低于90%

4.3 数据库/实例级别指标

# 数据库访问平均响应时间database_access_resp_time_rule:metrics-name:database_access_resp_timeop:">"threshold:100period:10count:3silence-period:5message:数据库访问平均响应时间超过100ms# 实例JVM内存告警instance_jvm_old_gc_time_rule:metrics-name:instance_jvm_young_gc_time# 或 old_gc_timeop:">"threshold:1000period:10count:1silence-period:5message:实例{name}JVM GC时间超过1s

4.4 完整的内置指标速查表

+------------------------------------------------------------------+ | 常用告警指标速查表 | +------------------------------------------------------------------+ | 指标名称 | 含义 | 典型阈值 | +------------------------------------------------------------------+ | service_resp_time | 服务平均RT | > 1000ms | | service_sla | 服务成功率 | < 99% | | service_cpm | 服务每分钟调用| > 5000 | | service_apdex | 服务Apdex分 | < 0.9 | | endpoint_avg | 端点平均RT | > 2000ms | | endpoint_sla | 端点成功率 | < 95% | | endpoint_cpm | 端点每分钟调用| > 1000 | | database_access_resp_time | DB平均RT | > 50ms | | database_access_sla | DB成功率 | < 99% | | instance_jvm_old_gc_time | Old GC耗时 | > 2000ms | | instance_jvm_young_gc_time | Young GC耗时 | > 1000ms | | instance_jvm_young_gc_count | Young GC次数 | > 10/min | | instance_cpu_percentage | CPU使用率 | > 80% | | instance_jvm_memory_heap_usage | 堆内存使用率 | > 85% | +------------------------------------------------------------------+

5. 自定义告警规则实战

5.1 场景一:慢端点聚合告警

假设你的系统有200个端点,不想每个端点超时都单独告警。可以创建一个"全局慢端点数量"告警:

# 先定义OAL脚本(oal/core.oal)// 统计过去10分钟平均响应时间>2s的端点数 slow_endpoint_count = from(Endpoint.latency) .filter(latency>2000) .count();# alarm-settings.yml中引用slow_endpoint_count_rule:metrics-name:slow_endpoint_countop:">"threshold:10period:10count:1silence-period:10message:当前有{value}个端点的响应时间超过2秒,请检查系统健康状态

5.2 场景二:错误率突增告警

# OAL脚本endpoint_error_rate = from(Endpoint.*).filter(status == false) .count() .percentage();endpoint_error_burst_rule:metrics-name:endpoint_error_rateop:">"threshold:5# 错误率超过5%period:5count:2silence-period:5message:端点{name}错误率飙升至{value}%,请立即检查!

5.3 场景三:业务级别的自定义指标

// 在业务代码中埋点importorg.apache.skywalking.apm.toolkit.meter.MeterFactory;importio.micrometer.core.instrument.Counter;@ComponentpublicclassOrderMetrics{privatestaticfinalCounterORDER_FAIL_COUNTER=MeterFactory.counter("order_fail_total").tag("type","payment").build();publicvoidrecordOrderFail(Stringreason){ORDER_FAIL_COUNTER.increment();}}

然后通过Prometheus Fetcher将自定义指标导入SkyWalking(v9+支持),或使用OpenTelemetry桥接。

6. 告警通知渠道配置

6.1 Webhook(通用回调)

# alarm-settings.ymlwebhooks:-http://your-webhook-service:8080/alarm

Webhook的POST请求体格式如下:

[{"scopeId":1,"scope":"SERVICE","name":"order-service","id0":1,"id1":0,"ruleName":"service_resp_time_rule","alarmMessage":"服务 order-service 的响应时间超过 1000ms,当前值: 2345ms","startTime":1617800000000}]

自定义Webhook处理服务示例

@RestController@RequestMapping("/alarm")publicclassAlarmWebhookController{@PostMappingpublicResponseEntity<String>handleAlarm(@RequestBodyList<AlarmMessage>alarms){for(AlarmMessagealarm:alarms){// 1. 记录到数据库alarmLogService.save(alarm);// 2. 按严重级别路由if(isCritical(alarm)){urgentNotifyService.send(alarm);// 电话/短信}else{normalNotifyService.send(alarm);// 群消息/邮件}// 3. 自动创建工单ticketService.createTicket(alarm);}returnResponseEntity.ok("received");}privatebooleanisCritical(AlarmMessagealarm){returnalarm.getAlarmMessage().contains("成功率")||alarm.getAlarmMessage().contains("错误率");}}

6.2 钉钉(DingTalk)通知

dingtalkHooks:# 钉钉群机器人Webhook URL-url:https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN# 加签密钥(安全设置)secret:YOUR_SECRET

钉钉机器人收到的消息格式:

【SkyWalking告警】 告警规则: service_resp_time_rule 告警服务: order-service 告警消息: 服务 order-service 的响应时间超过 1000ms,当前值: 2345ms 告警时间: 2026-07-02 14:30:00

6.3 企业微信(WeChat)通知

wechatHooks:-url:https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY

6.4 Slack通知

slackHooks:-url:https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK

6.5 通知渠道配置对比图

+------------------------------------------------------------------+ | 告警通知渠道对比 | +------------------------------------------------------------------+ | | | 渠道 | 配置复杂度 | 到达率 | 适用场景 | +------------------------------------------------------------------+ | Webhook | ⭐⭐⭐ | 自定义 | 自定义告警处理流程 | | DingTalk | ⭐⭐ | ★★★★ | 国内企业团队首选 | | WeChat | ⭐⭐ | ★★★★★ | 微信办公场景 | | Slack | ⭐⭐ | ★★★★ | 国际化团队/国外企业 | | Feishu | ⭐⭐ | ★★★★ | 飞书用户 | +------------------------------------------------------------------+

7. 告警静默与分级

7.1 静默期(silence-period)

silence-period是告警系统的"冷却时间":

rules:service_resp_time_rule:silence-period:30# 告警后30分钟不再重复

工作流程:

+------------------------------------------------------------------+ | 告警静默期工作原理 | +------------------------------------------------------------------+ | | | 时间线: | | ──────────────────────────────────────────────────────────────→ | | | | 14:00 触发告警 ✅ 🔔 发送通知 | | 14:05 再次触发 🔇 静默中,不发送 | | 14:15 再次触发 🔇 静默中,不发送 | | 14:30 静默期结束 | | 14:35 再次触发 ✅ 🔔 发送通知(新一轮告警开始) | | | +------------------------------------------------------------------+

7.2 告警分级策略

在大型系统中,告警需要分级处理。可以通过多个规则实现:

rules:# P3 - 低优先级:响应时间超过1秒service_resp_time_p3:metrics-name:service_resp_timeop:">"threshold:1000period:10count:3silence-period:30message:[P3]服务{name}响应时间超过1秒# P2 - 中优先级:响应时间超过3秒service_resp_time_p2:metrics-name:service_resp_timeop:">"threshold:3000period:5count:2silence-period:10message:[P2]服务{name}响应时间超过3秒,需要关注# P1 - 高优先级:成功率低于95%service_sla_p1:metrics-name:service_slaop:"<"threshold:95period:3count:1silence-period:5message:[P1]🚨 服务{name}成功率低于95%,请立即处理!# P0 - 紧急:成功率低于80%service_sla_p0:metrics-name:service_slaop:"<"threshold:80period:2count:1silence-period:3message:[P0]🔥 服务{name}成功率暴跌至{value}%,需要立即介入!

7.3 告警分级处理流程图

+------------------------------------------------------------------+ | 告警分级处理流程 | +------------------------------------------------------------------+ | | | 告警触发 | | │ | | ┌──────────┼──────────┐ | | ▼ ▼ ▼ | | P3 P2 P0/P1 | | 低优先级 中优先级 高优先级 | | │ │ │ | | ▼ ▼ ▼ | | ┌────────┐ ┌────────┐ ┌────────┐ | | │钉钉群 │ │钉钉群 │ │电话+短信│ | | │普通消息│ │@值班人 │ │+钉钉@all│ | | └────────┘ └────────┘ └────────┘ | | │ │ │ | | ▼ ▼ ▼ | | ┌────────┐ ┌────────┐ ┌────────┐ | | │自动记录│ │自动建 │ │自动建 │ | | │工单 │ │工单+ │ │工单+ │ | | │ │ │排期 │ │拉群 │ | | └────────┘ └────────┘ └────────┘ | +------------------------------------------------------------------+

8. 告警配置的生产级最佳实践

8.1 告警抑制

当某个上游服务挂了,所有下游服务都会告警——这叫"告警风暴"。SkyWalking的告警目前原生不支持抑制,但可以通过Webhook端实现:

// 告警抑制逻辑示例publicclassAlarmSuppressor{privateMap<String,Long>suppressedServices=newConcurrentHashMap<>();publicbooleanshouldSuppress(AlarmMessagealarm){// 如果上游服务已告警,抑制下游StringserviceName=alarm.getName();Stringupstream=getUpstream(serviceName);if(suppressedServices.containsKey(upstream)){log.info("抑制告警: {} (因上游 {} 已告警)",serviceName,upstream);returntrue;}returnfalse;}}

8.2 告警通知的黄金法则

  1. 宁可漏报,不可滥报:告警噪音是运维最大的敌人
  2. P0告警必须有人响应:配置值班表和升级机制
  3. 告警信息要有上下文:不只是"CPU高了",而是"order-service的CPU达到90%,正值业务高峰期"
  4. 告警要有"药方":附带Runbook链接,告诉运维该怎么处理
  5. 定期复盘告警:哪些告警是误报?哪些阈值需要调整?

8.3 动态阈值 vs 静态阈值

+------------------------------------------------------------------+ | 静态阈值 vs 动态阈值 | +------------------------------------------------------------------+ | | | 静态阈值: | | "服务响应时间超过1秒就告警" | | ┌────────────────────────────────┐ | | │ 优点: 简单直接,一目了然 │ | | │ 缺点: 不区分白天/夜间/高峰期 │ | | │ 低峰期1秒可能正常 │ | | └────────────────────────────────┘ | | | | 动态阈值: | | "服务响应时间超过历史均值的2倍就告警" | | ┌────────────────────────────────┐ | | │ 优点: 自适应,减少误报 │ | | │ 缺点: 实现复杂,需要历史数据 │ | | │ SkyWalking原生暂不支持 │ | | │ 可通过Prometheus+AlertManager │ | | │ 结合实现动态阈值 │ | | └────────────────────────────────┘ | +------------------------------------------------------------------+

8.4 生产环境完整告警配置示例

# alarm-settings.yml 生产级配置rules:# ========== 服务级别 ==========service_resp_time_rule:metrics-name:service_resp_timeop:">"threshold:1000period:10count:3silence-period:30message:"[P3] 服务 {name} 平均响应时间 {value}ms"service_sla_rule:metrics-name:service_slaop:"<"threshold:95period:5count:2silence-period:10message:"[P1] 服务 {name} 成功率降至 {value}%"# ========== 数据库 ==========database_access_resp_time_rule:metrics-name:database_access_resp_timeop:">"threshold:100period:10count:3silence-period:10message:"[P2] 数据库访问平均延迟 {value}ms"# ========== JVM ==========instance_jvm_old_gc_time_rule:metrics-name:instance_jvm_old_gc_timeop:">"threshold:2000period:5count:1silence-period:10message:"[P2] 实例 {name} Full GC时间 {value}ms"instance_jvm_memory_heap_usage_rule:metrics-name:instance_jvm_memory_heap_usageop:">"threshold:85period:10count:2silence-period:10message:"[P2] 实例 {name} 堆内存使用率 {value}%"# ========== 通知渠道 ==========webhooks:-http://alarm-gateway.internal:8080/api/alarmdingtalkHooks:-url:https://oapi.dingtalk.com/robot/send?access_token=xxxsecret:xxx

9. 总结

SkyWalking的告警系统像一位不知疲倦的哨兵:

  • 指标选得好:从服务、端点、数据库到JVM,覆盖所有关键维度
  • 规则配得巧:period + count组合找到灵敏度与噪音的平衡
  • 通知发得准:Webhook/钉钉/企微/Slack多通道,分级通知
  • 静默设得稳:silence-period防止告警风暴

把告警想象成你手机的"勿扰模式"——重要电话(P0/P1)永远不静音,普通通知(P3)按你的节奏来。

下一篇文章,我们将回到一个看似"传统"但非常重要的场景——SkyWalking在单体应用中的应用,看看这个"云原生时代的APM"如何在"老系统"中发光发热。


上一篇【第21篇】用SkyWalking排查慢服务——从蛛丝马迹到真相大白
下一篇【第23篇】SkyWalking与单体应用——老系统也能焕发新活力