1. 先想清楚:这类需求的真实形态和三条推送技术路线
1.1 看似都是“新记录推企微”,其实背后是四种完全不同的业务场景
刚接到“监控数据表中的新记录并自动推送到企业微信群”这个需求时,千万别急着写代码。先搞清楚对方到底在监控什么表、推完之后要干什么,因为“新记录”这三个字在不同系统里的含义完全不一样:
- 电商/订单场景:订单表插入一条新订单,群里的运营或者客服需要第一时间看到,点击进去核单、审单、处理异常。
- 工单/审批场景:工单表插入新工单,需要提醒值班人员领取任务,甚至直接在企业微信里完成派单流转。
- IoT/设备告警场景:设备上报一条告警事件,群里收到提醒后需要快速判断是否升级、是否通知现场处理。
- 数据采集/导入场景:定时任务批量导入了上万条数据,数据表有新增,需要给相关方发一个汇总通知,而不是逐条轰炸。
这四种场景对实时性、消息格式、后续动作的要求差别很大。订单场景要求秒级响应,汇总场景一分钟一次也能接受;告警场景要求消息里带上级别和跳转详情页入口,工单场景则要求推送完之后还能走完一个“处理流程”。所以第一步永远不是选技术,而是把需求翻译成三个问题:监控哪张表、什么算新记录、推完之后人要干什么。
1.2 企业微信推送有三条路线,选错一条后面全得返工
企业微信的推送能力不是只有一种,我见过太多人一开始图省事全堆在群机器人上,做到一半发现没法点链接、没法关联审批,又推倒重来。三条路线对应的能力和代价差别很明显:
| 路线 | 核心能力 | 接入复杂度 | 典型使用场景 |
|---|---|---|---|
| 群机器人 Webhook | 向指定群推送文本/Markdown/图片/文件,支持@成员 | 极低,拿到Webhook地址即可 | 纯粹的提醒通知、告警播报 |
| 自建应用消息 | 按成员/部门/标签推送,可跳转H5/小程序,能拿到用户身份 | 中等,需要CorpID、Secret、AgentId,配置可信域名 | 需要点进详情页操作、处理工单 |
| 企业微信审批API | 创建审批实例,走公司审批流,自动留痕 | 较高,需要管理端审批应用权限 | 需要人工审核、多人会签的场景 |
如果你只是“群里有条记录出来了”,群机器人是最合适的;如果要求“点这条消息打开订单详情页去操作”,那就得用自建应用消息或者群机器人里的图文卡片配合公网H5;如果整个流程必须留痕、必须走审批,那就直接对接审批API。这节不展开具体参数,后面第3节和第4节会分别给出实操代码。
1.3 动手之前先定三个设计目标
我每次帮团队做这种监控推送服务,都会先逼着对方定三个指标,不然中途必然扯皮:
第一是可容忍延迟。有些业务要求5秒内必须提醒,有些30秒轮询一次已经很奢侈。延迟要求直接决定了你用轮询还是用Binlog监听,后面会细说。第二是容错级别。漏掉一条新订单的代价有多大?如果只是漏一条没太大关系,那程序可以做得简单很多;如果一条都不能漏,就得上消息确认、状态持久化、失败重推。第三是消息量上限。平时一天几十条和一天几万条,推送侧的限流策略完全不同,企业微信群机器人每分钟只能发20条,批量大时必须合并发送。
这些目标先和需求方对齐,再往后选型,才不容易返工。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数据表新记录监控:轮询、触发器、CDC三种实现怎么选
2.1 轮询方案:代码量最小,但搞清楚边界再上
轮询的原理最简单:每隔几秒执行一次查询,找出“上次处理之后新增的记录”。
一般的写法是记录上次处理的最大主键ID,每次查询WHERE id > last_id ORDER BY id ASC LIMIT n,处理完一批就更新last_id。成本低、侵入性小,不需要改数据库结构,也不需要引入新组件,这是它最受欢迎的原因。
但这个方案有两个坑必须提前知道。第一个坑是依赖自增主键连续性。如果业务代码里手动插入过指定ID的数据、或者做过数据回滚和批量导入,主键ID的“大小顺序”和“插入时间顺序”就可能不一致。第二个坑更隐蔽:在多个事务并发写入时,主键大的事务可能先提交,主键小的事务后提交。如果查询结果先看到了主键101,把last_id推进到101,主键100的行才提交,那这一条就永远漏掉了。
要降低这个风险,推荐的做法是在SQL里加一个时间兜底窗口,或者把created_at也纳入判断条件。比如查询改成:
sql复制SELECT id, order_no, amount, created_at
FROM orders
WHERE id > %(last_id)s
AND created_at < NOW() - INTERVAL 2 SECOND
ORDER BY id ASC
LIMIT %(batch_size)s
这样最近两秒内新插入但尚未最终确认的行不会被立刻消费,给并发事务留一个提交窗口。代价是增加了最多2秒的延迟,但对绝大多数推送提醒场景完全可接受。
2.2 触发器+队列表:可控性居中,适合你说了算的库
如果担心轮询漏数据,又不想引入重组件,可以在数据库里做触发器,把新记录写进一张队列表,程序只消费队列表:
sql复制CREATE TRIGGER trg_order_after_insert
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
INSERT INTO table_monitor_queue(table_name, pk_id, create_time)
VALUES ('orders', NEW.id, NOW());
END;
然后监控程序就是定时SELECT ... FROM table_monitor_queue WHERE processed = 0 ORDER BY id。因为触发器插入队列表的时机和业务写入是同一个事务,所以只要业务数据提交了,队列表里就一定有记录,基本不会漏。
但触发器方案也有代价。它会在数据库实例上增加写入开销,高并发表上触发器数量一多,对主库性能有影响;而且每次加表监控都要新写一条触发器,数据库变更需要走脚本审核,很多公司这一步卡得非常严。如果你自己就是数据库的owner,触发器是个不错的中间选择;如果还需要DBA批准,我建议先掂量一下沟通成本。
2.3 Binlog/CDC方案:专业但重,适合监控全变更
轮询和触发器只能看到“插入后的结果”,看不到update、delete,也拿不到变更前后对比。如果业务对账、审计需要完整的变更流,就得考虑基于Binlog的CDC方案,常见的有Canal、Debezium、Flink CDC。
CDC的核心机制是把自己伪装成数据库的从库,消费Binlog日志,数据只要在数据库里发生任何变更,几乎实时流转出来。严格意义上它不只是“监控新记录”,而是完整的change data capture。这个方案实时性最强、信息量最大,但
