
国庆长假线上值班机器人GLM 5.3 接入企业微信与报警短信智能降噪国庆长假的这几天刚好轮到我排班线上值班。对于维护着两百多个微服务、上千个容器节点的架构团队来说长假值班往往是一场对神经耐受力的严峻考验。平时在工位上多块大屏常驻 Grafana看板大家各司其职告警响了有人顺手点开排查。但到了放假所有告警都集中轰炸到值班人员的手机和企业微信上。仅仅是网络骨干网一次 50ms 的轻微抖动Prometheus、Cat 和微服务健康检查组件就会在半分钟内连环触发 80 多条报警短信与群推送。大部分告警都是瞬时恢复的“狼来了”但你又绝不敢把群消息静音因为你不知道哪一条夹杂在几十条抖动信息里的“订单库活跃连接数打满”是真的致命 P1 故障。长期处于这种告警疲劳Alert Fatigue状态人不仅无法好好休息更容易在真正出事时麻痹大意。为了根治这个问题在假期前一周我们基于智谱 GLM 5.3 大模型与企业微信群机器人搭了一套报警智能降噪与根因聚类服务。这几天线上稳定跑下来手机从每天上百次震动缩减为每天 4 次高可信摘要排查效率反而翻倍。告警洪峰的症结与聚类思路监控系统之所以会产生海量噪声根本原因在于单点探测无法感知拓扑因果。例如底层的公共 Redis 集群由于某台宿主机网卡重置中断了 3 秒钟依赖该缓存的用户服务抛出 JedisConnectionException订单服务调用用户服务失败抛出 DubboTimeoutException网关感知到下游响应过慢抛出 Gateway 504 熔断告警消息队列消费者反压积压告警被激活。监控系统会机械地将上述 4 层的每台机器指标逐条发送给值班人员。但从架构师的视角来看这起事件有且仅有一个事实“底层某台 Redis 发生网络短暂抖动导致下游链路出现连锁超时3 秒后已自愈”。我们设计的降噪架构逻辑非常纯粹第一步时间窗口聚合。Alertmanager 的 Webhook 不直接外发而是先灌入应用内部的 90 秒缓冲池。第二步拓扑与日志富化。从缓冲池捞出一批告警提取报错堆栈摘要、受影响的应用名。第三步GLM 5.3 根因聚类。将多条原始事件打包给大模型让其结合系统依赖关系进行归因判断影响范围与修复建议。第四步企业微信卡片推送。同一类根因在指定静音窗口内合并更新禁止刷屏。核心实现从接收聚合到大模型归因1. Alertmanager Webhook 聚合器首先在 Spring Boot 中暴露一个接收端点将告警灌入基于并发安全队列的时间窗口收集器package com.yali.ops.alert; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; RestController RequestMapping(/internal/alert) public class AlertWebhookController { private final AlertAggregationEngine engine; public AlertWebhookController(AlertAggregationEngine engine) { this.engine engine; } PostMapping(/receive) public String receiveAlerts(RequestBody AlertPayload payload) { if (payload ! null payload.getAlerts() ! null) { engine.enqueue(payload.getAlerts()); } return SUCCESS; } }收集器内部采用定时调度器每隔 90 秒清空一次暂存区打包进入聚类流程package com.yali.ops.alert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; Component public class AlertAggregationEngine { private static final Logger log LoggerFactory.getLogger(AlertAggregationEngine.class); private final ConcurrentLinkedQueueAlertItem queue new ConcurrentLinkedQueue(); private final GlmAnalysisService glmAnalysisService; private final WeComNotificationService weComService; public AlertAggregationEngine(GlmAnalysisService glmAnalysisService, WeComNotificationService weComService) { this.glmAnalysisService glmAnalysisService; this.weComService weComService; } public void enqueue(ListAlertItem items) { queue.addAll(items); } Scheduled(fixedDelay 90_000) public void processBatch() { if (queue.isEmpty()) { return; } ListAlertItem batch new ArrayList(); AlertItem item; while ((item queue.poll()) ! null) { batch.add(item); } log.info(提取到报警批次共 {} 条开始请求 GLM 5.3 聚类分析..., batch.size()); try { AlertSummary summary glmAnalysisService.analyze(batch); if (summary.isNeedNotify()) { weComService.sendMarkdownCard(summary); } } catch (Exception e) { log.error(报警分析或通知异常, e); } } }2. 构建 GLM 5.3 专家 Prompt 与结构化提取大模型最擅长阅读凌乱但具备语义关联的文本。我们在 Prompt 中对 GLM 5.3 赋予“资深 SRE 架构师”角色并约束其输出严格的 JSON 结构。package com.yali.ops.alert; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.ai.chat.client.ChatClient; import org.springframework.stereotype.Service; import java.util.List; Service public class GlmAnalysisService { private final ChatClient chatClient; private final ObjectMapper objectMapper new ObjectMapper(); public GlmAnalysisService(ChatClient.Builder chatClientBuilder) { this.chatClient chatClientBuilder.build(); } public AlertSummary analyze(ListAlertItem alerts) { String alertJson; try { alertJson objectMapper.writeValueAsString(alerts); } catch (Exception e) { alertJson alerts.toString(); } String systemPrompt 你是一位资深分布式系统 SRE 专家。 以下是在过去 90 秒内系统捕获的一批监控告警日志。 请分析这些告警之间的因果关联完成以下任务 1. 识别核心根因Root Cause过滤掉因上游超时引发的连锁下游告警 2. 评估当前系统整体健康风险等级P0/P1/P2/INFO 3. 判断是否需要值班人员立即登录机器介入如果已自动恢复或纯属网络瞬断且无业务损伤标记 needNotifyfalse 4. 给出一键排查命令建议如检查某端口连接数、JVM 堆栈等。 必须严格返回如下 JSON 格式禁止任何额外前导词 { severity: P1, rootCause: 简明扼要的一句话根因, impactScope: 受影响的核心业务模块, status: 已自动恢复 / 持续恶化中, needNotify: true, troubleshootingTip: 推荐执行的排查命令或操作路径 } ; String response chatClient.prompt() .system(systemPrompt) .user(alertJson) .call() .content(); try { // 清理可能包含的 markdown 标签 String cleanJson response.replaceAll(json, ).replaceAll(, ).trim(); return objectMapper.readValue(cleanJson, AlertSummary.class); } catch (Exception e) { // 解析失败时的降级兜底直接组装简单通知 AlertSummary fallback new AlertSummary(); fallback.setSeverity(P2); fallback.setRootCause(解析聚合异常原始报警共 alerts.size() 条); fallback.setNeedNotify(true); return fallback; } } }3. 企业微信群卡片渲染与静音防轰炸将降噪后的结果格式化为美观的 Markdown 消息发送到企业微信群。对于持续发生的同一根因事件利用本地缓存进行哈希锁定30 分钟内只更新不重报package com.yali.ops.alert; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; Service public class WeComNotificationService { private final RestClient restClient; private final String webhookUrl; private final ConcurrentHashMapString, Long silenceCache new ConcurrentHashMap(); public WeComNotificationService(Value(${ops.wecom.webhook}) String webhookUrl) { this.webhookUrl webhookUrl; this.restClient RestClient.create(); } public void sendMarkdownCard(AlertSummary summary) { String silenceKey summary.getSeverity() : summary.getRootCause(); Long lastTime silenceCache.get(silenceKey); long now System.currentTimeMillis(); // 同一类告警在 30 分钟内静音抑制 if (lastTime ! null (now - lastTime) 30 * 60 * 1000L) { return; } silenceCache.put(silenceKey, now); String markdown String.format( ### 智能值班哨兵诊断报告 [%s] **根因归纳**%s **影响范围**%s **当前状态**%s **建议操作**%s *系统已自动将 90 秒内 50 条级联告警降噪压缩请按需介入。* , summary.getSeverity(), summary.getRootCause(), summary.getImpactScope(), summary.getStatus(), summary.getTroubleshootingTip() ); MapString, Object body Map.of( msgtype, markdown, markdown, Map.of(content, markdown) ); restClient.post() .uri(webhookUrl) .contentType(MediaType.APPLICATION_JSON) .body(body) .retrieve() .toBodilessEntity(); } }假期线上实战复盘在国庆假期第四天上午这套系统打了一场极其漂亮的仗。当天上午 10:14机房骨干网交换机出现短时丢包。如果在过去几十个业务微信群会同时刷出上百条 Dubbo 超时和连接断开告警值班人员得挨个点进去看堆栈确认哪儿坏了。而这一次企业微信哨兵机器人在 10:16 准时推送了一条聚合卡片等级P2黄色预警根因IDC 跨机房专线网络在 10:14:02 发生约 4 秒丢包导致订单微服务调用营销中心出现 12 次超时重试。状态下游重试均已成功链路当前已完全恢复无数据积压。建议无需人工登录介入保持监控观察。看完这条卡片我只需要扫一眼核心指标大盘确认 QPS 和错误率恢复平缓连笔记本电脑都无需打开。把大语言模型用在运维场景中不一定非要去搞全自动自愈或者高大上的端到端自治。先从最折磨工程师的“告警降噪”切入把散乱的指标重组为人看得懂的因果逻辑就能释放巨大的生产力。技术不仅要为业务兜底也要真正善待每一个在节假日坚守岗位的人。