SkyWalking 告警通知渠道集成:Webhook、Slack、钉钉、企业微信
Apache SkyWalking 支持多种告警通知渠道集成。 Webhook、Slack、钉钉和企业微信的配置方法。通过 alarm-settings.yml 配置规则,结合 Java 示例实现自定义路由与消息增强。涵盖安全性、避免告警风暴及测试最佳实践,帮助构建可靠的运维告警体系。

Apache SkyWalking 支持多种告警通知渠道集成。 Webhook、Slack、钉钉和企业微信的配置方法。通过 alarm-settings.yml 配置规则,结合 Java 示例实现自定义路由与消息增强。涵盖安全性、避免告警风暴及测试最佳实践,帮助构建可靠的运维告警体系。

在现代微服务架构和云原生应用中,可观测性(Observability)已成为保障系统稳定性和快速故障定位的关键能力。Apache SkyWalking 作为一款开源的 APM(Application Performance Monitoring)系统,凭借其强大的分布式追踪、指标监控和拓扑分析能力,被广泛应用于各类复杂系统中。然而,仅仅收集和展示数据是远远不够的——当系统出现异常时,及时、准确地将告警信息通知到相关责任人,才是实现'主动运维'的核心环节。
SkyWalking 内置了灵活的告警机制,支持通过多种渠道发送告警通知,包括 Webhook、Slack、钉钉(DingTalk)、企业微信(WeCom)等。本文将深入探讨如何配置和集成这些通知渠道,帮助你构建一个高效、可靠的告警响应体系。
在深入集成细节之前,我们首先需要理解 SkyWalking 告警机制的基本工作原理。SkyWalking 的告警功能主要由 告警规则(Alarm Rules) 和 通知渠道(Notifiers) 两部分组成。
告警规则定义了'在什么条件下触发告警'。这些规则基于 SkyWalking 收集的各类指标(如服务响应时间、错误率、吞吐量等)进行判断。规则通常包含以下要素:
service_resp_time(服务平均响应时间)、service_sla(服务成功率)等。service_resp_time > 1000 表示当服务平均响应时间超过 1000 毫秒时触发。period: 10 表示在过去 10 分钟内持续满足条件才触发。SkyWalking 的告警规则配置文件通常位于 config/alarm-settings.yml 中。一个简单的规则示例如下:
rules:
# 规则名称
service_resp_time_rule:
# 监控的指标名
metrics-name: service_resp_time
# 阈值,单位毫秒
threshold: 1000
# 检查周期(分钟)
period: 10
# 在周期内,有多少次检查超过阈值才触发告警
count: 3
# 告警级别
severity: WARNING
# 告警消息模板
message: "服务 {name} 的平均响应时间在过去 {period} 分钟内超过了 {threshold}ms"
当告警规则被触发后,SkyWalking 需要将告警信息发送出去。这就是通知渠道的作用。SkyWalking 本身不直接实现所有渠道的发送逻辑,而是通过 Webhook 机制作为核心枢纽。对于 Slack、钉钉、企业微信等第三方平台,SkyWalking 提供了内置的 Webhook 集成,你只需提供对应的 Webhook URL 即可。
整个告警流程可以概括为:
alarm-settings.yml 中定义的规则,定期评估指标是否达到告警条件。下面,我们将逐一介绍如何集成这四种主流的通知渠道。
Webhook 是一种轻量级的、基于 HTTP 的回调机制。它允许一个应用在特定事件发生时,向另一个应用的 URL 发送一个 POST 请求。在 SkyWalking 的告警场景中,OAP Server 就是 Webhook 的发送方,而你的自定义服务就是接收方。
在 config/alarm-settings.yml 文件中,找到 webhook 配置项。你可以配置一个或多个 Webhook URL。
webhook:
# 可以配置多个 Webhook 地址
- http://your-webhook-service:8080/skywalking-alarm
- https://another-webhook-endpoint.com/notify
接下来,我们需要创建一个简单的 Spring Boot 应用来接收 SkyWalking 发送的告警。这个应用的核心是一个处理 POST 请求的 Controller。
首先,添加必要的依赖(pom.xml):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
然后,定义一个 POJO 来映射 SkyWalking 发送的告警 JSON 结构。根据 SkyWalking 官方文档,告警消息的结构大致如下:
import java.util.List;
public class AlarmMessage {
// 告警消息内容
private String message;
// 告警时间(时间戳)
private long alarmTime;
// 告警级别
private String severity;
// 触发告警的实体(如服务名、实例名等)
private List<Scope> scope;
// 触发告警的规则名称
private String ruleName;
// Getters and Setters
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public long getAlarmTime() { return alarmTime; }
public void setAlarmTime(long alarmTime) { this.alarmTime = alarmTime; }
public String getSeverity() { return severity; }
public void setSeverity(String severity) { this.severity = severity; }
public List<Scope> getScope() { return scope; }
public void setScope { .scope = scope; }
String { ruleName; }
{ .ruleName = ruleName; }
{
String name;
String id;
String type;
String { name; }
{ .name = name; }
String { id; }
{ .id = id; }
String { type; }
{ .type = type; }
}
}
现在,创建一个 Controller 来处理告警请求:
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
@RestController
@RequestMapping("/skywalking")
public class SkyWalkingAlarmController {
private static final Logger logger = LoggerFactory.getLogger(SkyWalkingAlarmController.class);
/**
* 接收 SkyWalking 的告警 Webhook
* @param alarmMessages SkyWalking 发送的告警消息列表
*/
@PostMapping("/alarm")
public void receiveAlarm(@RequestBody List<AlarmMessage> alarmMessages) {
for (AlarmMessage alarm : alarmMessages) {
logger.info("Received SkyWalking alarm: {}", alarm.getMessage());
// 在这里,你可以执行任何自定义逻辑
// 例如:记录到数据库、发送邮件、调用其他内部系统等
// 示例:根据告警级别决定处理方式
if ("CRITICAL".equals(alarm.getSeverity())) {
triggerPagerDuty(alarm);
} else {
sendToInternalChat(alarm);
}
}
}
private void triggerPagerDuty(AlarmMessage alarm) {
// 模拟触发 PagerDuty 的逻辑
logger.warn("CRITICAL ALARM! Triggering PagerDuty for: {}", alarm.getMessage());
}
private void sendToInternalChat(AlarmMessage alarm) {
// 模拟发送到内部聊天工具
logger.info("Sending to internal chat: {}", alarm.getMessage());
}
}
启动这个 Spring Boot 应用后,确保 SkyWalking OAP Server 能够访问到 http://your-webhook-service:8080/skywalking/alarm 这个地址。当告警触发时,你就能在应用的日志中看到接收到的消息。
webhook:
- url: http://your-webhook-service:8080/skywalking-alarm
headers:
- Authorization: Bearer your-secret-token
- X-Custom-Header: custom-value
通过 Webhook,我们为 SkyWalking 告警打开了通往无限可能的大门。接下来,我们将看看如何利用 SkyWalking 内置的支持,快速集成几个流行的即时通讯工具。
Slack 是全球范围内广泛使用的团队协作工具,其强大的 Incoming Webhooks 功能使其成为接收系统告警的理想选择。SkyWalking 对 Slack 的集成非常直接,本质上也是通过 Webhook 实现的,但提供了更友好的配置方式。
#alerts),然后点击 'Allow'。https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX。将上一步复制的 Webhook URL 添加到 config/alarm-settings.yml 的 slackHooks 配置项中。
slackHooks:
# 可以配置多个 Slack Webhook
- https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
默认情况下,SkyWalking 会发送一个包含告警信息的简单文本消息。如果你希望消息更美观、信息更丰富(例如使用 Slack 的 Blocks 或 Attachments),你需要使用前面介绍的 通用 Webhook 方式,并在你的接收服务中构造符合 Slack 格式的 JSON。
不过,对于大多数场景,SkyWalking 的默认格式已经足够清晰。一个典型的 Slack 告警消息如下:
[WARNING] Rule: service_resp_time_rule Service: user-service Message: 服务 user-service 的平均响应时间在过去 10 分钟内超过了 1000ms
POST JSON -> SkyWalking OAP Server -> Slack Incoming Webhook -> Slack Server -> Slack Channel #alerts -> Team Members
通过以上几步,你的 SkyWalking 告警就能实时推送到 Slack 频道中,让团队成员第一时间知晓系统异常。
钉钉是中国企业广泛使用的办公通讯和协同平台。与 Slack 类似,钉钉也提供了'自定义机器人'功能,用于接收外部系统的通知。SkyWalking 同样内置了对钉钉机器人的支持。
https://oapi.dingtalk.com/robot/send?access_token=your_access_token。在 config/alarm-settings.yml 中,找到 dingtalkHooks 配置项。
dingtalkHooks:
# 钉钉 Webhook URL
webhook: https://oapi.dingtalk.com/robot/send?access_token=your_access_token
# 如果使用了'加签'安全设置,需要在这里配置密钥
secret: your_dingtalk_robot_secret
# 可选:@群里的所有人
atAll: false
重要提示:secret 字段仅在你在钉钉机器人设置中选择了'加签'时才需要填写。如果选择的是'IP 地址'或'关键词'白名单,则不需要 secret。
SkyWalking 会将告警信息封装成钉钉支持的 Markdown 消息格式,使得消息在钉钉中展示得更加清晰和专业。一个典型的钉钉告警消息会包含告警级别、规则名称、服务名和详细信息,并以不同颜色区分警告和严重级别。
POST with Sign -> SkyWalking OAP Server -> DingTalk Custom Robot -> DingTalk Server -> DingTalk Group Chat -> Team Members
通过钉钉集成,国内团队可以无缝地将 SkyWalking 告警融入到日常的办公沟通流中,极大地提升了告警的触达效率。
企业微信(WeCom)是腾讯推出的企业级通讯与办公工具,在中国市场同样拥有庞大的用户基础。它也提供了'群机器人'功能来接收外部告警。
https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=your_webhook_key。在 config/alarm-settings.yml 中,找到 wechatHooks 配置项。
wechatHooks:
# 企业微信 Webhook URL
webhook: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=your_webhook_key
企业微信的群机器人目前主要通过 Webhook URL 进行身份验证,无需额外的密钥(除非你对企业微信后台有更复杂的权限控制)。
SkyWalking 会将告警信息以文本消息的形式发送到企业微信群。虽然不如钉钉的 Markdown 格式丰富,但关键信息(如服务名、告警内容、时间)都会清晰呈现。
POST -> SkyWalking OAP Server -> WeCom Group Robot -> WeCom Server -> WeCom Internal Group -> Team Members
至此,我们已经完成了四种主流通知渠道的集成。无论你的团队使用哪种沟通工具,SkyWalking 都能确保告警信息及时送达。
虽然 SkyWalking 的内置集成非常方便,但在实际生产环境中,你可能需要更精细的控制。例如,你可能希望:
severity)将告警发送到不同的渠道(如 CRITICAL 发送到 Slack,WARNING 发送到钉钉)。这些需求超出了 SkyWalking 内置通知器的能力范围,此时就需要回到我们最强大的武器——自定义 Webhook 服务。
我们可以扩展之前的 Spring Boot Webhook 服务,实现一个智能的告警路由器。
// ... 其他 import
@RestController
@RequestMapping("/skywalking")
public class SmartAlarmRouter {
private static final Logger logger = LoggerFactory.getLogger(SmartAlarmRouter.class);
// 假设这些是你的配置,可以从配置中心读取
private final String slackWebhookUrl = "https://hooks.slack.com/services/...";
private final String dingtalkWebhookUrl = "https://oapi.dingtalk.com/robot/send?access_token=...";
@PostMapping("/smart-alarm")
public void routeAlarm(@RequestBody List<AlarmMessage> alarmMessages) {
for (AlarmMessage alarm : alarmMessages) {
try {
if ("CRITICAL".equals(alarm.getSeverity()) || "ERROR".equals(alarm.getSeverity())) {
// 严重告警发送到 Slack
sendToSlack(alarm);
} else if ("WARNING".equals(alarm.getSeverity())) {
// 警告发送到钉钉
sendToDingTalk(alarm);
} else {
// 其他级别记录日志
logger.info("Low severity alarm, logged only: {}", alarm.getMessage());
}
} catch (Exception e) {
logger.error("Failed to route alarm: {}", alarm.getMessage(), e);
}
}
}
Exception {
Map<String, Object> payload = <>();
payload.put(, String.format(, alarm.getSeverity(), alarm.getRuleName(), alarm.getMessage()));
();
restTemplate.postForEntity(slackWebhookUrl, payload, String.class);
logger.info();
}
Exception {
Map<String, Object> content = <>();
content.put(, );
content.put(, String.format(,
alarm.getSeverity(), alarm.getMessage(), alarm.getRuleName(), alarm.getMessage(), .util.Date(alarm.getAlarmTime())));
Map<String, Object> markdown = <>();
markdown.put(, );
markdown.put(, content);
();
restTemplate.postForEntity(dingtalkWebhookUrl, markdown, String.class);
logger.info();
}
}
在这个示例中,我们的 Webhook 服务不再只是一个被动的接收者,而是一个主动的决策中心。它根据告警的严重程度,动态地选择最合适的通知渠道。这种模式极大地增强了告警系统的灵活性和适应性。
另一个常见的需求是丰富告警内容。SkyWalking 的告警消息模板(message)是静态的。为了包含动态信息,比如一个慢请求的 Trace ID,你需要在规则中使用 SkyWalking 的 Dynamic Configuration 功能,或者在自定义 Webhook 服务中,根据告警中的服务名和时间范围,反向查询 SkyWalking 的 GraphQL API 来获取更多上下文。
例如,在 Webhook 服务中,你可以构造一个 GraphQL 查询,查找在告警时间点附近、响应时间最长的 Trace,并将其 ID 附加到最终的告警消息中。这需要你对 SkyWalking 的 GraphQL API 有一定了解,但这无疑是提升告警价值的关键一步。
成功集成告警渠道只是第一步,要构建一个真正可靠、高效的告警系统,还需要遵循一些最佳实践。
这是告警系统中最常见的问题。当一个底层服务故障时,可能会引发上游数十甚至上百个服务的连锁告警,导致通知渠道被刷屏,真正的根因被淹没。
每一条告警都应该包含足够的信息,让值班人员能够立即采取行动。一个模糊的'服务响应慢'远不如'订单服务在 14:30-14:35 期间 P99 响应时间 > 2s,主要慢在调用库存服务'有用。
alarm-settings.yml 中,充分利用可用的变量(如 {name}, {value}, {period})。你的告警渠道本身也可能出问题。如果 Slack 服务不可用,你的告警就失效了。
Webhook URL 本质上是公开的入口点,必须加以保护。
不要等到生产环境出问题才发现告警没发出来。
test-mode,可以在不触发真实规则的情况下,向配置的渠道发送测试消息。通过本文的详细讲解,我们全面探索了 Apache SkyWalking 告警通知渠道的集成方法。从最通用的 Webhook,到针对 Slack、钉钉、企业微信的内置支持,再到高级的自定义路由和内容增强,我们一步步构建了一个强大而灵活的告警通知体系。
记住,告警不是目的,快速恢复业务才是。一个优秀的告警系统应该像一位经验丰富的哨兵,只在真正需要你关注的时候才发出清晰、准确、可操作的信号,而不是在深夜用无意义的噪音将你惊醒。通过合理配置 SkyWalking 的告警规则,并结合本文介绍的渠道集成技巧,你完全有能力打造出这样一个值得信赖的哨兵。
现在,就去检查你的 alarm-settings.yml 文件,优化你的告警规则,并为你的团队选择最合适的告警渠道吧!

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online