微信开发中的消息排重机制实现
安安 2018-03-14 来源 :网络 阅读 3096 评论 0

摘要:本篇微信开发的文章将为大家讲解微信开发的消息排重机制实现。

本篇微信开发的文章将为大家讲解微信开发的消息排重机制实现。


摘要: 微信公众平台开发时,微信推送消息的机制是推送过来后如果5秒内收不到响应则认为没有推送成功,会再次推送,总共推送三次。如果我们服务器接收到消息没有及时响应,就会微信的触发“重推机制”,这就需要我们在服务端对微信推送过来的消息进行排重。


微信公众平台开发时,微信推送消息的机制是推送过来后如果5秒内收不到响应则认为没有推送成功,会再次推送,总共推送三次。如果我们服务器接收到消息没有及时响应,就会微信的触发“重推机制”,这就需要我们在服务端对微信推送过来的消息进行排重。


我们不应该让服务器出现处理时间过长的情况,对于业务复杂、处理时间长度不可控的代码可以进行异步处理,每次接收到微信推送后都立即返回空串,当然这是另外一回事了,不是今天要说的。

 

先看微信公众号开发文档原文

普通消息

1、关于重试的消息排重,推荐使用msgid排重。
2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

事件推送:

微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次

关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。
假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

微信推送过来的消息无外乎上面两种,微信文档也给出了排重方法,下面说说我的方案:

方案一

1. 创建判断重复消息的DuplicateRemovalMessage类;

2. 把微信推送的消息解析赋值给DuplicateRemovalMessage对象实例;

3. 用静态变量List当缓存,判断DuplicateRemovalMessage实例是否存在于缓存list中,如果存在则为重复消息,如果不存在则不是重复消息并把消息放到缓存List中。

此方案弊端:

1. 缓存list会无限增大,所以用setMessageToCache方法限制了list最大容量为1000;

2. 解决了list最大容量依然还有弊端,就是两条重复的消息之间如果有超过999个DuplicateRemovalMessage对象依然会判断不准,只能增大list容量来缓解。

实现代码:
别忘记复写hashcode、equals方法

public class DuplicateRemovalMessage {

 

    private String MsgId;

    

    private String FromUserName;

    

    private String CreateTime;

 

    @Override

    public int hashCode() {

        final int prime = 31;

        int result = 1;

        result = prime * result + ((CreateTime == null) ? 0 : CreateTime.hashCode());

        result = prime * result + ((FromUserName == null) ? 0 : FromUserName.hashCode());

        result = prime * result + ((MsgId == null) ? 0 : MsgId.hashCode());

        return result;

    }

 

    @Override

    public boolean equals(Object obj) {

        if (this == obj)

            return true;

        if (obj == null)

            return false;

        if (getClass() != obj.getClass())

            return false;

        DuplicateRemovalMessage other = (DuplicateRemovalMessage) obj;

        if (CreateTime == null) {

            if (other.CreateTime != null)

                return false;

        } else if (!CreateTime.equals(other.CreateTime))

            return false;

        if (FromUserName == null) {

            if (other.FromUserName != null)

                return false;

        } else if (!FromUserName.equals(other.FromUserName))

            return false;

        if (MsgId == null) {

            if (other.MsgId != null)

                return false;

        } else if (!MsgId.equals(other.MsgId))

            return false;

        return true;

    }

      省略set和get方法...

 

}

方案一升级版

方案一的解决并不优雅,而且无法在负载均衡环境下使用。

改进方式是在【方案一】的基础上,使用redis替换List作为存储中介,将DuplicateRemovalMessage对象存储到redis中,存储的key可以用msgId,事件消息可以用FromUserName + CreateTime 拼接,同时给对象设置一个15秒的超时时间,这样就不会有List那种集合存储元素无限增多的情况。

最后

微信推送消息的CreateTime 精确到秒值,这就可能出现一个用户正常操作的情况下触发两条FromUserName 和CreateTime 完全相同的消息,也就是说按照微信文档上提供的排重方法会过滤掉合法数据,我在线上环境遇到过一次。

我们微信公众号开启了获取用户地理位置的功能,用户打开微信后点击菜单进入了某个页面,此时微信后台向我们推送了用户地理位置事件消息和用户点击公众号菜单事件消息,这两个消息的CreateTime 和FromUserName 相同。

所以最后建议做排重的时候,事件消息使用FromUserName + CreateTime+Event三个字段进行排重。

本文最初发布在iteye,由于iteye编辑博客内容提示我有敏感词,可是又不告诉我是哪个敏感词(真2b),无法编辑老文章,所以文章和更新以后都发到这里了。
(全文完)


以上,关于微信开发的全部内容讲解完毕啦,欢迎大家继续关注!更多关于微信开发的干货请关注职坐标微信开发频道!

 

本文由 @安安 发布于职坐标。未经许可,禁止转载。
喜欢 | 2 不喜欢 | 0
看完这篇文章有何感觉?已经有2人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved