MQtt向某一设备推送消息

先说明下背景:emq集群为2个节点,配置为4核16G,同时在线设备量大概在10W左右(即每个节点负载约5W)。

需求就是:需要向这其中的某3万设备推送某个消息。

解读下需求:比如我现在有设备号码是 1-100000 的这么些设备,要推送 30000-60000 的这些设备一些消息。

怎么实现呢?

目前有两种思路,且听我一一道来。

思路一:利用emq的保留消息实现。这也是我第一次想到并付诸于实践的思路。

保留消息的特点是,发布到topic的消息如果是保留消息的话,那么订阅这个topic的设备上线后将收到此消息。

那么可以这样设计:

设备端,每个设备都订阅自己独有的topic,例如用自己唯一的设备号,比如

1号设备订阅:private/1

2号设备订阅:private/2

这样在发布的时候,就可以向上面 private/30000 到 private/60000 这些topic发布保留消息,然后也只有对应订阅了这些topic的设备能收到了。

但是,嘿嘿,凡事都有但是。这种实现有两个问题:

1,鉴于保留消息的机制(一个topic只保留一条最新消息),同时只能像某个设备推送一条消息,举个例子:

在向 private/1 发了保留消息推送第一条消息【1号1号,再不上线就分手!】时,若1号设备一直不在线,而这时候你等不及又推了第二条消息【都是你的错!分手吧!】。这时如果1号设备联网上线了,就只会收到第二条消息,到最后也不知道为啥被分了手。

2,emq服务器在上述背景下,推送几千条的保留消息,就会把cpu跑满!这个问题,我反馈咨询过emq的开发人员,emq存数据是用的mnesia数据库,如果有大量保留消息的时候,每个设备上线时,都会到这个库查看是否有此设备所订阅topic匹配的路由数据。我的理解是,emq在存在大量保留消息,且上下线频繁的场景下,还做的不够好。

思路二:利用 redis+emq的上下线数据 实现。

鉴于保留消息有以上的问题,肯定行不通了,后来有想到一种思路。解决了这个问题。

设计思路:

设备端,每个设备订阅自己独有的topic,这个不变。

而发布端,不再发保留消息到emq,而是发到redis。在redis内,为每个设备维护一个待推送数据列表。利用redis的set数据结构来实现。比如:

1号设备的待推送列表为set结构的,key的结构为:retain:1

然后往这个key里面存要发布的指令,然后再利用emq的上下线消息,一上线,就去redis查 retain:1 下有没有待推送数据,有就推送,这样就实现了向独立设备推送独立消息的需求。推完之后可以删掉此消息,或者再设计一个回执反馈,待设备发回了某些特定回执之后再删也可以。并且,set结构的key能够存多条数据,只要内容不一样,所以可以解决上面保留消息第一点的问题。

至于上面第二点的问题,redis数据存在内存,吞吐极大,性能没有问题。

以上,笔者用第二种方式实现了上述背景下的需求,经过长时间验证,性能和可持久性都可靠。

郑重声明:帖子标题写有 【亲测】即能正常运行,帖子标题有 【原版】字样即原始版本自带有加密文件版本 限于标题长度字数限制问题,部分资源未注明开源情况均为原版文件(原版文件未做解密处理,但不影响使用)爱集码不会自己加密代码文件,源码仅供研究学习之用,请勿用于商业运营,商业运营请支持作者,购买正版,谢谢 特别提醒:本站所有下载资源均不包含技术支持和安装服务! 如需技术支持联系客服有偿解决,终身会员视情况而定,一般小问题免费解决。 重要提示:本站对于 Safari浏览器兼容不好,如出现下载按钮消失请换360或者QQ等第三方浏览器访问或下载。 免责申明:本站仅提供学习的平台,所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,并不承担任何法律责任,如果对您的版权或者利益造成损害,请提供相应的资质证明,我们将于3个工作日内予以删除。
资源猫 » MQtt向某一设备推送消息

提供最优质的资源集合

资源猫 立即查看