最近遇到一个MQTT上传包体达到了5M,且上传速度较快,处理完毕后内存也没有下降的趋势,只有当服务器内存不够用的时候才会回收一小部分内存,导致内存飞涨,同一服务器上的其他服务根本无法提供稳定的服务。
站在用户的角度思考问题,与客户深入沟通,找到朗县网站设计与朗县网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站建设、成都网站制作、企业官网、英文网站、手机端网站、网站推广、域名申请、网页空间、企业邮箱。业务覆盖朗县地区。
这种情况基本可以确定为byte[]太大,直接分配到堆上面了,而堆上的大对象要2代GC才能够回收,但是二代GC又懒又慢,啥时候回收这部分内存完全看心情。
雪崩的时候没有一片雪花是无辜的
1. 解决数组租用的问题
既然心里已经大概有了解决的方案那这事情就很明朗了
一个固定数组的租用使用 ArrayPoolT 这个对象去进行数组的租用,但是这个玩意对于使用者有点不太友好,申请的长度并不是实际需要的长度,这对于一些需要使用固定长度进行计算的地方就很蛋疼了。所以需要对这个进行一个封装,将实际需要的长度存储起来作为这个数组的长度,超过的全部作废掉。
那这个类的基本设计就应该是下面这样的,有一个 Length 去决定从 ArrayPoolT 租出来的数组到底有多少是可用长度。
2.要对数组进行指针操作.NET给我们提供了 Span 的API,但是这个没办法在Class中使用,所以只能使用它的同胞兄弟 MemoryT ,这些玩意在网上到处都是介绍的,我在这里就不介绍了。
3.如果要减少流拷贝就需要将这个类加上一个 Clone 的函数,直接让其他人调用Clone函数,就不会出现流拷贝太多导致多次分配堆的问题。
那么综上所需,出来的封装类应该就是这样的
再针对这个搞点拓展函数
搞定 完事
MQTT设计了一套保证消息稳定传输的机制,包括消息应答、存储和重传。
为了保证消息被正确的接收
在这套机制下,提供了三种不同层次QoS(Quality of Service):
QoS 是消息的发送方(Sender)和接受方(Receiver)之间达成的一个协议:
::: warning
QoS是Sender和Receiver之间的协议,而不是Publisher和Subscriber之间的协议。
换句话说,Publisher发布了一条QoS1的消息,只能保证Broker能至少收到一次这个消息;
而对于Subscriber能否至少收到一次这个消息,还要取决于Subscriber在Subscribe的时候和Broker协商的QoS等级。
:::
QoS0等级下,Sender和Receiver之间一次消息的传递流程如下:
Sender向Receiver发送一个包含消息数据的PUBLISH包,然后不管结果如何,丢掉已发送的PUBLISH包,一条消息的发送完成。
QoS1要保证消息至少到达一次,所以有一个应答的机制。Sender和Receiver的一次消息的传递流程如下:
1.Sender向Receiver发送一个带有数据的PUBLISH包,并在本地保存这个PUBLISH包;
2.Receiver收到PUBLISH包以后,向Sender发送一个PUBACK数据包,PUBACK数据包没有消息体(Payload),在可变头中有一个包标识(Packet Identifier),和它收到的PUBLISH包中的Packet Identifier一致。
3.Sender收到PUBACK之后,根据PUBACK包中的Packet Identifier找到本地保存的PUBLISH包,然后丢弃掉,一次消息的发送完成。
但是消息传递流程中可能会出现问题:
相比QoS0和QoS1,QoS2不仅要确保Receiver能收到Sender发送的消息,还需要确保消息不重复。它的重传和应答机制就要复杂一些,同时开销也是最大的。QoS2下,一次消息的传递流程如下所示:
1.Sender发送QoS为2的PUBLISH数据包,数据包 Packet Identifier 为 P,并在本地保存该PUBLISH包;
2.Receiver收到PUBLISH数据包后,在本地保存PUBLISH包的Packet Identifier P,并回复Sender一个PUBREC数据包,PUBREC数据包可变头中的Packet Identifier为P,没有消息体(Payload);
3.当Sender收到PUBREC,它就可以安全的丢弃掉初始Packet Identifier为P的PUBLISH数据包。同时保存该PUBREC数据包,并回复Receiver一个PUBREL数据包,PUBREL数据包可变头中的Packet Identifier为P,没有消息体;
4.当Receiver收到PUBREL数据包,它可以丢掉保存的PUBLISH包的Packet Identifier P,并回复Sender一个可变头中 Packet Identifier 为 P,没有消息体(Payload)的PUBCOMP数据包;
5.当Sender收到PUBCOMP包,那么认为传输已完成,则丢掉对应的PUBREC数据包;
上面是一次完整无误的传输过程,然而传输过程中可能会出现以下情况:
针对上述的问题,较为详细的处理方法如下:
Receiver收到PUBREL数据包后,正式将消息递交给上层应用层,投递之后销毁Packet Identifier P,并发送PUBCOMP数据包,销毁之前的持久化消息。
之后不管接收到多少个PUBREL数据包,因为没有Packet Identifier P,直接回复PUBCOMP数据包即可。
在 MQTT 协议中,从 Broker 到 Subscriber 这段消息传递的实际 QoS 等于:Publisher 发布消息时指定的 QoS 等级和 Subscriber 在订阅时与 Broker 协商的 QoS 等级,这两个 QoS 等级中的最小那一个。
Actual Subscribe QoS = MIN(Publish QoS, Subscribe QoS)
如果 Client 想接收离线消息,必须使用持久化的会话(Clean Session = 0)连接到 Broker,这样 Broker 才会存储 Client 在离线期间没有确认接收的 QoS 大于 等于1 的消息。
在以下情况下你可以选择 QoS0:
在以下情况下你应该选择 QoS1:
在以下情况下你应该选择 QoS2:
网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。
MQTT物联网PLC网关即wtblnet iot Gateway,是一款支持单网口/两网口/五网口,支持4G/3G/WIFI/PPPOE/WAN有线网络,
内嵌工业控制协议,支持远程自定义配置、远程部署、网关状态监控等技术于一体的内嵌网络操作系统的工业级智能网关。
水利MQTT网关就是水利工程中所有的水利电机、传感器等设备接入到MQTT物联网协议网络。
电力MQTT网关就是电力工程中所有的电机、传感器,发电设备等等设备接入到MQTT物联网协议网络。
水利MQTT网关物联网协议,电力MQTT网关物联网协议传送到客户自定义的MQTT云平台,方便用户利用先进的物联网技术和两化融合技术快速构建一套高效、高并发的工业互联网系统及工业4.0服务平台。
好像,其中WG585工业智能网关在远程监控解决方案。
JMeter 内置 HTTP/HTTPS、TCP 等支持多种协议,还具备插件扩展机制。
MQTT 协议作为物联网界的主流协议,虽然并非 JMeter 自带的协议类型,但在物联网测试场景中极为普遍。为了支持 MQTT 协议的规模测试,EMQ 映云科技开发了基于 JMeter 的 MQTT 协议开源测试插件: 。
经过几个版本的迭代,目前 JMeter MQTT 插件的最新版本为 2.0.2,支持连接、消息发布、消息订阅等多种采样器,并可通过组合构建更复杂的测试场景。
本文我们将具体介绍如何在 JMeter 中使用 MQTT 插件。
MQTT 插件的安装方式与其他 JMeter 第三方插件类似。
连接采样器模拟物联网设备,发起 MQTT 连接。
Server name or IP: 指向被测 MQTT 服务器地址。
Port number: 以 EMQ X 为例,默认 TCP 连接的端口是 1883, SSL 连接则是 8883。具体的端口请参照服务器的具体配置。
MQTT version : 目前支持 MQTT 3.1及3.1.1版本。
Timeout: 连接超时设置,以秒为单位。
Protocols: 支持TCP、SSL、WS 和 WSS 方式连接 MQTT 服务器。当选择 SSL 或 WSS 加密通道连接时,可以选择单向或者双向认证(Dual)。如果希望进行双向认证,还需要指定相应的客户端证书(p12证书),以及对应的文件保护密码(Secret)。
User authentication: 如果 MQTT 服务器配置了用户认证,需要提供相应的用户名( User name )和密码( Password )。
ClientId: 虚拟用户的标识。如果勾选了「Add random suffix for ClientId」,将会在 ClientId 的基础上给每个虚拟用户再添加一个 uuid 串作为后缀,整个作为虚拟用户标识。
Keep alive(s): 心跳信号发送间隔。例如,300 表示客户端每隔 300 秒向服务器发出 ping 请求,以保持连接活跃。
Connect attempt max: 第一次连接过程中,尝试重连的最大次数。超过该次数则认为连接失败。如果希望一直尝试重连,可以设为 -1。
Reconnect attempt max: 后继连接过程中,尝试重连的最大次数。超过该次数则认为连接失败。如果希望一直尝试重连,可以设为 -1。
Clean session : 如果希望在连接之间保留会话状态,可以将该选项设为 false。如果不希望在新的连接中保留会话状态,则将该项设为true。
消息发布采样器复用连接采样器中建立的 MQTT 连接,向目标 MQTT 服务器发布消息。
QoS Level: 服务质量,取值为 0,1,2,分别代表 MQTT 协议规范里的至多一次(AT_MOST_ONCE),至少一次(AT_LEAST_ONCE),精确一次(EXACTLY_ONCE)
Retained messages : 如果希望使用「保留消息」,可将该选项设为 true,MQTT 服务器端将会存储插件发布的保留消息及其 QoS,并在相应 topic 上发生订阅时,直接将最后一条保留消息投递给订阅端,使得订阅端不必等待即可获取发布端的最新状态值。
Topic name: 发布消息所属的主题。
Add timestamp in payload: 如果勾选,发布的消息体开头会附带当前时间戳,配合消息订阅采样器的 Payload includes timestamp 选项,可以在消息接收端计算消息达到的延时。如果不勾选则只发送实际的消息体。
Payloads Message type: 目前支持三种消息类型
消息发布采样器复用连接采样器中建立的 MQTT 连接,从目标 MQTT 服务器上订阅消息。
QoS Level: 服务质量,含义与消息发布采样器相同。
Topic name(s): 订阅消息所属的主题。支持单个消息订阅采样器订阅多个主题,主题之间用逗号分隔。
Payload includes timestamp: 如果勾选,会从消息体开头处解析发送时间戳,配合消息发布采样器的 Add timestamp in payload 选项,可以用于计算消息的接收延时。如果不勾选则只解析实际的消息体。
Sample on : 采样方式,默认为" specified elapsed time(ms) ",即每隔指定的毫秒时间采样一次。也可以选择" number of received messages ",即每接收到指定的消息数采样一次。
Debug response: 如果勾选,消息内容会打印在 JMeter 的响应结果中。该选项主要用于调试目的,正式运行测试不建议勾选,以免影响测试效率。
断开连接采样器中建立的 MQTT 连接。
本文我们介绍了 JMeter MQTT 插件的各测试组件,在下期文章中我们将针对不同的测试场景详细介绍如何用 MQTT 插件来构建测试脚本。
原地址:
原文链接:
MQTT客户端软件MQTT.fx的使用详解
使用说明
mqtt.fx打开后的主页面如下:
点击齿轮进行连接设置
本地连接设置:
用户信息设置:
SSL安全证书设置:
网络代理设置:
遗嘱设置:
连接测试
1、启动mosquitto
地址,下一步配置使用
2、在主机中打开MQTT.FX软件
设置连接信息
IP为mosquitto所在的IP,端口号默认为1883。
点击进行连接
连接成功以后可以进行发布订阅。
你用什么编码方式发送的数据,你就要用对应的方式在接收端解码呀