EMQ百万级MQTT消息服务(小技巧)

2024-05-28 01:32

本文主要是介绍EMQ百万级MQTT消息服务(小技巧),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

				版权声明:本文为博主原创文章,未经博主允许不得转载。					https://blog.csdn.net/u011142688/article/details/79852325				</div><div id="content_views" class="markdown_views"><!-- flowchart 箭头图标 勿删 --><svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg><p><img src="http://i.imgur.com/vhdeDvX.png" alt="" title=""></p>

附上:

喵了个咪的博客:w-blog.cn
EMQ官方地址:http://emqtt.com/
EMQ中文文档:http://emqtt.com/docs/v2/guide.html

1.ACL鉴权规则化

在正常业务使用下对于客户端的行为可以使用ACL进行限制,比如A客户端只能订阅 /A/get 队列消息和向 /A/set 发布内容
但是在MYSQL里面处理这样的鉴权就需要写入两条记录,如果设备量有一百万数据库就要承担两百万条鉴权数据量会大大影响数据库的性能
那么有没有什么批量的方式来定义ACL鉴权呢?

在mysql-ACL鉴权的配置文件下关于如何使用鉴权的SQL是可以编辑的,也就意味着你可以通过SQL来实现批量ACL鉴权规则

> vim /usr/local/emqttd/etc/plugins/emq_auth_mysql.conf# 最下面有这样一条配置
auth.mysql.acl_query = select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'
  • 1
  • 2
  • 3
  • 4

笔者这里就实现每个设备默认可以订阅 /A/get 队列消息和向 /A/set 发布

笔者现在的规则是客户端只能向hello写消息其他操作一概不允许,我们先加两条记录

insert `mqtt_acl`(`allow`,`username`,`access`,`topic`) values(1,'$all',1,'/$user/get');
insert `mqtt_acl`(`allow`,`username`,`access`,`topic`) values(1,'$all',2,'/$user/set');
  • 1
  • 2

然后修改默认的ACL鉴权的SQL语句如下(这里使用的是username作为topic动态名称也可以使用其他字段):

select allow, ipaddr, username, clientid, access, REPLACE(topic,'$user','%u') from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'
  • 1

这样一来就算没有独立配置/A/set可以写入,作为用户是A的客户端也可以进行消息的写入了,并且也可以监听消息/A/get

2.共享订阅

关于队列常见的使用中也有这样的场景,一条消息希望被多个监听程序接收到,可能的场景如下:

  • 一个程序处理,一个程序记录日志分别处理
  • 批量推送
                            ---------|       | --Msg1,Msg2,Msg3--> Subscriber1
Publisher--Msg1,Msg2,Msg3-->|  EMQ  | --Msg1,Msg2,Msg3--> Subscriber2|       | --Msg1,Msg2,Msg3--> Subscriber3---------
  • 1
  • 2
  • 3
  • 4
  • 5

多条消息希望被多个程序中的某个进行处理,场景如下:

  • 并发情况下耗时操作进行并行处理提高系统吞吐量
                            ---------|       | --Msg1--> Subscriber1
Publisher--Msg1,Msg2,Msg3-->|  EMQ  | --Msg2--> Subscriber2|       | --Msg3--> Subscriber3---------
  • 1
  • 2
  • 3
  • 4
  • 5

在默认情况下有多个客户端监听一个事件时会受到同样的消息,但是怎么共享订阅呢?EMQ共享订阅支持两种使用方式:

  • [Math Processing Error]queue/如:share/group/topic

以上两种都可以实现共享订阅(笔者测试下来值通过了share来完成了订阅),订阅和监听

  • 多个服务端监听 $share/group/topic
  • 客户端向 topic 发送消息

3.Qos 0/1/2的区别实测

最多一次的传输
消息是基于TCP/IP网络传输的。没有回应,在协议中也没有定义重传的语义。消息可能到达服务器1次,也可能根本不会到达。

至少一次的传输
服务器接收到消息会被确认,通过传输一个PUBACK信息。如果有一个可以辨认的传输失败,无论是通讯连接还是发送设备,还是过了一段时间确认信息没有收到,发送方都会将消息头的DUP位置1,然后再次发送消息。消息最少一次到达服务器。SUBSCRIBE和UNSUBSCRIBE都使用level 1 的QoS。
如果客户端没有接收到PUBACK信息(无论是应用定义的超时,还是检测到失败然后通讯session重启),客户端都会再次发送PUBLISH信息,并且将DUP位置1。
当它从客户端接收到重复的数据,服务器重新发送消息给订阅者,并且发送另一个PUBACK消息。

笔者做了一个实现消费端阻塞2秒消费一个内容,发布端1秒发布一个内容,等EMQ的最大拥塞使用完了之后消息在EMQ缓存的会后就会出现很多的重复消息

只有一次的传输
在QoS level 1上附加的协议流保证了重复的消息不会传送到接收的应用。这是最高级别的传输,当重复的消息不被允许的情况下使用。这样增加了网络流量,但是它通常是可以接受的,因为消息内容很重要。
QoS level 2在消息头有Message ID。

4.密码加盐

在用户验证中可以使用plain | md5 | sha | sha256 | bcrypt等hash方式(默认使用的sha256),但是出于安全性考虑EMQ也支持对密码加盐,可以解开注释使用一下加盐方式中的一种

vim /usr/local/emqttd/etc/plugins/emq_auth_mysql.conf## sha256 with salt prefix
## auth.mysql.password_hash = salt,sha256## bcrypt with salt only prefix
## auth.mysql.password_hash = salt,bcrypt## sha256 with salt suffix
## auth.mysql.password_hash = sha256,salt## pbkdf2 with macfun iterations dklen
## macfun: md4, md5, ripemd160, sha, sha224, sha256, sha384, sha512
## auth.mysql.password_hash = pbkdf2,sha256,1000,20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

对应存储的密码就要进行加盐处理了

5.EMQ离线消息

  • 保留消息
    MQTT客户端向服务器发布(PUBLISH)消息时,可以设置保留消息(Retained Message)标志。保留消息(Retained Message)会驻留在消息服务器,后来的订阅者订阅主题时仍可以接收该消息。
    例如mosquitto命令行发布一条保留消息到主题’a/b/c’:
    mosquitto_pub -r -q 1 -t a/b/c -m ‘hello’
    之后连接上来的MQTT客户端订阅主题’a/b/c’时候,仍可收到该消息:
    $ mosquitto_sub -t a/b/c -q 1
    hello
    保留消息(Retained Message)有两种清除方式:
    客户端向有保留消息的主题发布一个空消息:
    mosquitto_pub -r -q 1 -t a/b/c -m ”
    消息服务器设置保留消息的超期时间。

  • cleanSession 清理回话
    MQTT客户端向服务器发起CONNECT请求时,可以通过’Clean Session’标志设置会话。
    ‘Clean Session’设置为0,表示创建一个持久会话,在客户端断开连接时,会话仍然保持并保存离线消息,直到会话超时注销。
    ‘Clean Session’设置为1,表示创建一个新的临时会话,在客户端断开时,会话自动销毁。

3 总结

在EMQ和MQTT使用过程中还有很多的细节需要注意,关注细节才能走的更远

注:笔者能力有限有说的不对的地方希望大家能够指出,也希望多多交流!

这篇关于EMQ百万级MQTT消息服务(小技巧)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1009167

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Java MQTT实战应用

《JavaMQTT实战应用》本文详解MQTT协议,涵盖其发布/订阅机制、低功耗高效特性、三种服务质量等级(QoS0/1/2),以及客户端、代理、主题的核心概念,最后提供Linux部署教程、Sprin... 目录一、MQTT协议二、MQTT优点三、三种服务质量等级四、客户端、代理、主题1. 客户端(Clien

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

如何在Mac上彻底删除Edge账户? 手动卸载Edge浏览器并清理残留文件技巧

《如何在Mac上彻底删除Edge账户?手动卸载Edge浏览器并清理残留文件技巧》Mac上的Edge账户里存了不少网站密码和个人信息,结果同事一不小心打开了,简直尴尬到爆炸,想要卸载edge浏览器并清... 如果你遇到 Microsoft Edge 浏览器运行迟缓、频繁崩溃或网页加载异常等问题,可以尝试多种方

qt5cored.dll报错怎么解决? 电脑qt5cored.dll文件丢失修复技巧

《qt5cored.dll报错怎么解决?电脑qt5cored.dll文件丢失修复技巧》在进行软件安装或运行程序时,有时会遇到由于找不到qt5core.dll,无法继续执行代码,这个问题可能是由于该文... 遇到qt5cored.dll文件错误时,可能会导致基于 Qt 开发的应用程序无法正常运行或启动。这种错

mtu设置多少网速最快? 路由器MTU设置最佳网速的技巧

《mtu设置多少网速最快?路由器MTU设置最佳网速的技巧》mtu设置多少网速最快?想要通过设置路由器mtu获得最佳网速,该怎么设置呢?下面我们就来看看路由器MTU设置最佳网速的技巧... 答:1500 MTU值指的是在网络传输中数据包的最大值,合理的设置MTU 值可以让网络更快!mtu设置可以优化不同的网