微信告警小程序实战开发:3步搭建消息推送、7天实现业务告警闭环
一听到“微信告警小程序”,第一反应就是“又要写代码了”。其实把这事拆开看,它的核心就两件事:怎么接收告警 和 怎么把告警推给微信。我见过不少团队卡在“消息推送”这一步,觉得非得自己搭服务器、配域名,其实微信生态里早就给了现成的路——只是不知道哪条路最省力。
一、选对推送通道:别一上来就写小程序
先纠正一个常见误区:告警小程序 ≠ 必须做一个完整的小程序应用。如果你只是想让服务器出问题时,微信能第一时间通知你,那最佳方案是“企业微信机器人”或者“微信测试号”。举个例子,我去年帮一个创业团队做运维告警,他们一开始非要开发一个完整的小程序,结果光审核就等了三天,而用企业微信群机器人,配置一个Webhook地址,10分钟就搞定了。
但如果你确实需要做一个“能展示告警历史、能手动确认告警”的小程序,那就要走正式的小程序开发流程。这里有个关键判断标准:告警接收人数少于10人,用企业微信机器人;需要多人协作、告警分类、历史查询,才值得做小程序。
二、小程序端:用云开发省掉服务器很多教程会教你去买云服务器、装Node.js、配Nginx,然后写一个后端接口。但2025年了,微信小程序自带的云开发已经能覆盖90%的告警场景。你只需要做三件事:
1. 创建云函数作为告警接收端
在微信开发者工具里,右键新建一个云函数,比如叫“alarmReceiver”。这个云函数的作用就是暴露一个HTTP接口,供你的监控系统(比如Prometheus、Zabbix)把告警数据POST进来。云函数代码很简单:
// 云函数入口文件
exports.main = async (event, context) => {
const { title, content, level } = JSON.parse(event.body);
// 存入数据库
const db = cloud.database();
await db.collection('alarms').add({
data: { title, content, level, time: new Date() }
});
// 如果是紧急告警,立刻通过模板消息推送给管理员
if (level === 'critical') {
await sendTemplateMessage(title, content);
}
return { code: 0 };
};
2. 用数据库做告警持久化
云开发自带MongoDB数据库,你不需要自己建表。直接在小程序里调用数据库API就能查询告警列表。这里有个技巧:给告警时间字段建索引,否则告警量大了以后,查询会越来越慢。在云开发控制台的数据库标签里,找到“alarms”集合,给“time”字段加一个降序索引。
3. 模板消息:让告警主动找上门
不知道,小程序是可以主动给用户发消息的——通过订阅消息。但注意,订阅消息需要用户主动点击“允许”才能推送。我建议你在小程序首页设计一个“开启告警通知”的按钮,引导用户订阅。代码示例:
wx.requestSubscribeMessage({
tmplIds: ['你的模板ID'],
success(res) {
// 用户点了允许,就可以调云函数发送了
}
});
这里有个坑:模板消息只能发给已经订阅过的用户,而且每个用户最多订阅3次。所以告警推送要精,不要每条日志都推,只推Critical级别的。
三、告警源对接:以Prometheus为例假设你的服务器监控用的是Prometheus,它自带的Alertmanager支持Webhook。你只需要在Alertmanager的配置里加一个receiver:
receivers:
- name: 'wechat'
webhook_configs:
- url: 'https://你的云函数地址/alarmReceiver'
send_resolved: true
注意send_resolved这个参数,设为true后,当告警恢复时,你的小程序也能收到“已恢复”的通知。这样你就不用再手动去查服务器状态了。
对比一下传统做法:以前你得自己写一个Web服务,部署在服务器上,还要处理HTTPS证书、域名备案。现在用云函数,URL直接是微信分配的,天然支持HTTPS,省掉一堆麻烦事。
四、告警聚合:别让消息刷屏告警系统最容易出现的问题就是消息风暴——服务器一抖动,微信能收到几百条告警。我见过最夸张的一次,一个团队因为磁盘告警阈值设得太低,半夜发了2000多条消息,最后所有人直接把群屏蔽了。
解决方案是在云函数里做告警聚合。比如,同一个IP的告警,5分钟内只发一条。代码逻辑:
// 查询最近5分钟是否有同IP的告警
const recent = await db.collection('alarms').where({
ip: event.ip,
time: _.gt(new Date(Date.now() - 5 * 60 * 1000))
}).count();
if (recent.total > 0) {
// 只更新数据库,不推送消息
return { code: 0, message: '已聚合' };
}
这个逻辑加进去之后,告警量能减少80%以上。用户收到的每一条消息,都是真正需要关注的。
五、升级玩法:加上告警认领和闭环基础告警推送做好之后,可以再加一个告警认领功能。比如运维A看到告警,点一下“我来处理”,其他运维就知道这事有人管了。实现方式:在告警详情页加一个按钮,调用云函数更新数据库里的“handler”字段。然后在小程序里用WebSocket实时同步状态变化。
云开发也支持WebSocket,但需要单独开通。如果不想搞太复杂,可以用轮询——每30秒查一次数据库,看告警状态有没有变化。对于告警场景,30秒的延迟完全可以接受。
最后说一个忽略的点:告警的标题和内容要可读。不要直接甩一堆JSON字段给用户。比如Prometheus告警的原始内容可能是:
{
"labels": {"alertname": "HighCPU"},
"annotations": {"summary": "CPU > 90%"}
}
你应该在云函数里把它转成:
⚠️ 紧急告警:CPU过高
服务器:192.168.1.100
当前值:95%
触发时间:2025-03-20 14:30:00
这样用户一眼就能看懂,不需要再打开电脑查详情。告警系统好不好用,往往就体现在这些细节上。

