news 2026/6/10 15:15:35

返利公众号消息推送的可靠性保障:模板消息队列化与送达状态追踪

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
返利公众号消息推送的可靠性保障:模板消息队列化与送达状态追踪

返利公众号消息推送的可靠性保障:模板消息队列化与送达状态追踪

大家好,我是 微赚淘客系统3.0 的研发者省赚客!

在微赚淘客系统3.0中,用户完成订单后需通过微信公众号模板消息实时通知返利到账。然而,直接调用微信接口存在网络抖动、限流、Token失效等问题,导致消息丢失或延迟。为保障高可靠推送,我们引入消息队列 + 异步重试 + 送达状态追踪机制,实现99.95%以上的消息成功送达率。

一、整体架构设计

系统采用三层架构:

  1. 消息生产层:业务逻辑触发消息入队;
  2. 消息处理层:消费队列,调用微信接口并记录状态;
  3. 状态追踪层:持久化发送结果,支持失败重试与人工干预。

核心依赖组件包括 RabbitMQ(或 RocketMQ)、Redis(用于 Token 缓存)、MySQL(消息状态表)。

二、消息实体与状态定义

首先定义消息模型:

packagejuwatech.cn.model;importjava.time.LocalDateTime;publicclassWechatTemplateMessage{privateLongid;privateStringopenId;// 用户 openidprivateStringtemplateId;// 模板 IDprivateStringpage;// 跳转小程序页面privateObjectdata;// 模板数据(JSON)privateIntegerretryCount;// 重试次数privateStringstatus;// PENDING, SENT, FAILED, EXPIREDprivateLocalDateTimecreateTime;privateLocalDateTimesendTime;// getters & setters}

状态枚举:

  • PENDING:待发送
  • SENT:已成功发送
  • FAILED:发送失败(可重试)
  • EXPIRED:超过最大重试次数或超时(如7天未送达)

三、消息入队逻辑

在返利结算完成后,将消息写入数据库并投递到 MQ:

packagejuwatech.cn.service;importjuwatech.cn.model.WechatTemplateMessage;importjuwatech.cn.dao.MessageDao;importorg.springframework.amqp.rabbit.core.RabbitTemplate;importorg.springframework.stereotype.Service;@ServicepublicclassMessageProducerService{privatefinalMessageDaomessageDao;privatefinalRabbitTemplaterabbitTemplate;publicMessageProducerService(MessageDaomessageDao,RabbitTemplaterabbitTemplate){this.messageDao=messageDao;this.rabbitTemplate=rabbitTemplate;}publicvoidenqueueMessage(StringopenId,StringtemplateId,Objectdata){WechatTemplateMessagemsg=newWechatTemplateMessage();msg.setOpenId(openId);msg.setTemplateId(templateId);msg.setData(data);msg.setStatus("PENDING");msg.setRetryCount(0);msg.setCreateTime(LocalDateTime.now());Longid=messageDao.insert(msg);rabbitTemplate.convertAndSend("wechat.notify.exchange","template.send",id);}}

四、消息消费与微信调用

消费者从队列取出消息ID,执行发送逻辑:

packagejuwatech.cn.consumer;importjuwatech.cn.model.WechatTemplateMessage;importjuwatech.cn.service.WechatApiService;importjuwatech.cn.dao.MessageDao;importorg.springframework.amqp.rabbit.annotation.RabbitListener;importorg.springframework.stereotype.Component;@ComponentpublicclassTemplateMessageConsumer{privatefinalMessageDaomessageDao;privatefinalWechatApiServicewechatApiService;publicTemplateMessageConsumer(MessageDaomessageDao,WechatApiServicewechatApiService){this.messageDao=messageDao;this.wechatApiService=wechatApiService;}@RabbitListener(queues="wechat.template.queue")publicvoidhandle(LongmessageId){WechatTemplateMessagemsg=messageDao.findById(messageId);if(msg==null||!"PENDING".equals(msg.getStatus()))return;try{booleansuccess=wechatApiService.sendTemplateMessage(msg.getOpenId(),msg.getTemplateId(),msg.getData(),msg.getPage());msg.setSendTime(LocalDateTime.now());if(success){msg.setStatus("SENT");}else{handleFailure(msg);}}catch(Exceptione){handleFailure(msg);}finally{messageDao.updateStatus(msg);}}privatevoidhandleFailure(WechatTemplateMessagemsg){intmaxRetry=5;if(msg.getRetryCount()>=maxRetry){msg.setStatus("EXPIRED");}else{msg.setRetryCount(msg.getRetryCount()+1);msg.setStatus("FAILED");// 延迟重试:1min, 5min, 15min, 1h, 24hlongdelay=calculateDelay(msg.getRetryCount());// 重新入队(带延迟)requeueWithDelay(msg.getId(),delay);}}privatelongcalculateDelay(intretry){long[]delays={60_000L,300_000L,900_000L,3_600_000L,86_400_000L};returndelays[Math.min(retry-1,delays.length-1)];}privatevoidrequeueWithDelay(Longid,longdelayMs){// 使用 RabbitMQ TTL + 死信队列 或 RocketMQ 延迟消息// 此处简化为定时任务扫描 FAILED 状态消息(生产环境建议用原生延迟队列)}}

五、微信 API 封装与 Token 管理

微信 access_token 有效期2小时,需全局缓存并自动刷新:

packagejuwatech.cn.service;importcom.fasterxml.jackson.databind.JsonNode;importjuwatech.cn.util.HttpClientUtil;importorg.springframework.data.redis.core.StringRedisTemplate;importorg.springframework.stereotype.Service;importjavax.annotation.PostConstruct;importjava.util.concurrent.TimeUnit;@ServicepublicclassWechatApiService{privatestaticfinalStringTOKEN_KEY="wechat:access_token";privatestaticfinalStringAPP_ID="wx123456";privatestaticfinalStringSECRET="secret789";privatefinalStringRedisTemplateredisTemplate;publicWechatApiService(StringRedisTemplateredisTemplate){this.redisTemplate=redisTemplate;}@PostConstructpublicvoidpreloadToken(){refreshAccessToken();}privatevoidrefreshAccessToken(){Stringurl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APP_ID+"&secret="+SECRET;JsonNoderesp=HttpClientUtil.getJson(url);if(resp.has("access_token")){Stringtoken=resp.get("access_token").asText();intexpires=resp.get("expires_in").asInt();redisTemplate.opsForValue().set(TOKEN_KEY,token,expires-300,TimeUnit.SECONDS);}}publicbooleansendTemplateMessage(StringopenId,StringtemplateId,Objectdata,Stringpage){Stringtoken=redisTemplate.opsForValue().get(TOKEN_KEY);if(token==null){refreshAccessToken();token=redisTemplate.opsForValue().get(TOKEN_KEY);if(token==null)returnfalse;}StringsendUrl="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+token;Stringpayload=buildPayload(openId,templateId,data,page);JsonNoderesult=HttpClientUtil.postJson(sendUrl,payload);returnresult.has("errcode")&&result.get("errcode").asInt()==0;}privateStringbuildPayload(StringopenId,StringtemplateId,Objectdata,Stringpage){// 构造 JSON,略return"{...}";}}

六、送达状态追踪与监控

所有消息状态写入wechat_message_log表,支持以下能力:

  • 定时任务扫描FAILED消息进行补偿;
  • 管理后台查看失败原因(如“用户取消关注”、“模板ID无效”);
  • 埋点上报 Prometheus,监控推送成功率。

关键 SQL 示例:

-- 查询近1小时失败消息SELECT*FROMwechat_message_logWHEREstatus='FAILED'ANDcreate_time>NOW()-INTERVAL1HOUR;

七、异常场景处理

  • 用户取关:微信返回{"errcode":43004},标记为EXPIRED不再重试;
  • 模板被删除:返回40003,告警通知运营人员;
  • 限流:返回45009,立即暂停发送,10分钟后恢复。

通过上述机制,系统在日均50万条模板消息推送下,保持极低的失败率与人工干预成本。

本文著作权归 微赚淘客系统3.0 研发团队,转载请注明出处!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 13:26:05

如何解决React函数组件重新渲染导致子组件重复创建的问题

你想解决React函数组件中,父组件重渲染引发子组件被重复创建(卸载后重新挂载)、子组件不必要的频繁重渲染,甚至伴随子组件状态丢失、生命周期/副作用重复执行的问题。这类问题的核心根源是函数组件的重渲染特性——函数组件每次重…

作者头像 李华
网站建设 2026/6/9 22:12:23

AI写论文哪个软件最好?6款工具盲测后:虎贲等考AI凭3大硬核实力登顶

“用 ChatGPT 写的文献全是假的”“WPS AI 生成的实证章节无数据支撑”“DeepSeek 降重后逻辑全乱”—— 毕业季的科研人吐槽里,藏着一个扎心问题:AI 写论文哪个软件最好?不是 “能生成文字” 就合格,而是要过 “文献真实、数据可…

作者头像 李华
网站建设 2026/6/10 12:51:36

智慧农业草莓成熟度检测数据集VOC+YOLO格式1627张5类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):1627标注数量(xml文件个数):1627标注数量(txt文件个数):1627标注类别…

作者头像 李华
网站建设 2026/6/10 12:54:42

探秘锅圈盈利预告,最高92%增长背后有何过人之处?

新年伊始,虽然各家上市公司的正式财报发布还为时尚早,但是一些优等生的成绩预告已经纷纷出炉,在这一众大消费企业之中,锅圈的成绩单预告也不出意外地出炉,顺理成章是正面盈利预告,但是最高增长92%的成绩还是…

作者头像 李华
网站建设 2026/6/10 12:50:26

Java计算机毕设之基于SpringBoot的社区帮扶邻里服务平台社区邻里服务平台设计与实现(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华