eclipse paho java_MQTT研究之EMQ:【eclipse的paho之java客户端使用注意事项】

这里,简单记录一下自己在最近项目中遇到的paho的心得,这里也涵盖EMQX的问题。

1. cleanSession

这个标识,是确保client和server之间是否持久化状态的一个标志,不管是client还是server重启还是连接断掉。下面是来自paho客户端源码的注释。

Sets whether the client and server should remember state across restarts and reconnects.

If set to false both the client and server will maintain state across restarts of the client, the server and the connection. As state is maintained:

Message delivery will be reliable meeting the specified QOS even if the client, server or connection are restarted.

The server will treat a subscription as durable.

If set to true the client and server will not maintain state across restarts of the client, the server or the connection. This means

Message delivery to the specified QOS cannot be maintained if the client, server or connection are restarted

The server will treat a subscription as non-durable

1)。 这个标志位,设置为true,那么,当连接断掉,例如,调用EMQX的接口踢掉连接,此时,即便重连上了(无论是通过autoconnect设置为true,还是在connectonLost这个回调函数里面配置上重连的逻辑),MQTT客户端程序都是无法进行重新订阅数据的。这个行为,说明session里面保存了会话所采用的topic信息。

2)。这个标志位,设置为true,autoconnect设置为false,在connectLost这个回调函数里面,自行实现重新连接的逻辑,并且再次针对相同的topic和qos进行订阅的话,当连接被踢掉,这个时候,会重新连接上,并且也会订阅上数据,只是会出现很奇怪的现象,CPU占用率比连接断开前提高很多。 我的应用(订阅到数据后,对数据进行相应的逻辑处理,正常情况下,一条数据大概1~5ms处理完)压测环境下,连接未断前,1.3W的并发,CPU空闲率在40%左右,重连之后,CPU的空闲率只有10%左右,这个地方是个大坑,目前我还没有搞清楚到底是什么原因导致,若有人遇到类似问题同仁,请给我留言,告知可能的原因。(我的paho是1.2.0版本,EMQX:V3.1.1)

3)。这个标志位,设置为false,autoconnect设置为false,在connectLost这个回调函数里面,自行实现重连的逻辑,但是不对topic进行重新订阅,即便连接断掉,重新连接上的话,依然会进行连接断开之前的业务逻辑,订阅到所需的数据,CPU的负荷也不会变大,基本和断开之前的状态持平。

下面配上connectLost这个回调函数(MqttCallback接口的一个方法)相关代码:

public voidconnectionLost(Throwable cause) {//连接丢失后,一般在这里面进行重连

System.out.println(">>>>>>>>>>>>>>>" +cause.getMessage());

System.out.println("连接断开,可以做重连");for (int i = 0; i < 3; i++) {if(reconnect()) {break;

}else{try{

Thread.sleep(i* 2);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}privateboolean reconnect() {try{

mqttClient.connect(mqttConnectOptions);

Thread.sleep(100);if( mqttClient.isConnected() ) {//mqttClient.subscribe(this.topic, 0);

return true;

}

}catch(MqttException e) {

e.printStackTrace();

}catch(InterruptedException e) {

e.printStackTrace();

}return false;

}

2.  EMQX的承压能力

网上标榜EMQX单节点处理能力多么牛逼,100W连接毫无压力,这个数值,其实呢,我觉得要仔细看测试场景,单单看连接数,其实没有什么意义,要看生产者消费者都存在的情况下,还有数据流通这种场景,连接能力或者数据处理能力如何。 我不是说100W连接能力是虚构的,我是想说纯粹的连接其实没有多大的价值,因为EMQX是消息总线,只有连接,不存在数据流动,有多大意义呢?

还是接着我上面的应用压测,我们团队开发的一个规则引擎,1.6W的消息并发(4000设备,每个设备每秒4条消息,当然是程序模拟出来的),规则引擎4C16G的服务器2台,每台跑3个实例,共享订阅两个EMQX节点(EMQX是集群),EMQX服务器配置4C16G。结果跑不了多久时间(1个小时不到,有时半个小时),就会出现EMQX平凡踢掉消费者连接的情况。

2019-09-19 14:22:42.710 [error] 0ba45c9872464c609c150f156e3f2a7e@10.95.198.25:52388[Connection] Shutdown exceptionally due to message_queue_too_long2019-09-19 14:22:55.746 [error] 4014030aed1642bba6ecec85debed172@10.95.198.26:60404[Connection] Shutdown exceptionally due to message_queue_too_long2019-09-19 14:23:08.131 [error] dde7f075ab2d45fdabfd192b5c6a4a30@10.95.198.25:52394[Connection] Shutdown exceptionally due to message_queue_too_long2019-09-19 14:23:14.374 [error] 72a25aca01164c8c8b4cf48451c4e316@10.95.198.25:52456[Connection] Shutdown exceptionally due to message_queue_too_long2019-09-19 14:23:41.686 [error] cd56963bfb4e4c0c8275abe9a24078de@10.95.198.26:60462[Connection] Shutdown exceptionally due to message_queue_too_long2019-09-19 14:23:52.638 [error] 4014030aed1642bba6ecec85debed172@10.95.198.26:60514[Connection] Shutdown exceptionally due to message_queue_too_long2019-09-19 14:24:06.015 [error] dde7f075ab2d45fdabfd192b5c6a4a30@10.95.198.25:52496[Connection] Shutdown exceptionally due to message_queue_too_long2019-09-19 14:24:13.541 [error] 0ba45c9872464c609c150f156e3f2a7e@10.95.198.25:52474 [Connection] Shutdown exceptionally due to message_queue_too_long

针对这个问题,我咨询过青云的EMQ团队的工程师,也在Github上咨询过EMQX的维护者,都反馈说是消费者处理速度太慢,emq的消息队列消息堆积导致。现象如此,怎么解决呢,似乎只能添加消费者服务,或者降低消息压力,EMQX能否提升性能呢?我觉得EMQX现在共享订阅的能力不行,就这4000个连接投递消息,1.6W的并发,4000个topic,采用共享订阅的方式,性能感觉不是很好,是我们程序设计的有问题,还是EMQX共享订阅性能真的有待提升?为什么这么说能,我们测试过非共享订阅,就是明确订阅某个指定topic。非共享订阅情况下,相同的服务器上,比共享订阅性能好很多很多(差不多一半)。。。(欢迎探讨)

从EMQX的配置中,针对上面这种消息队列太长的问题,emqx.conf的配置文件中有相关信息,参考下面这个错误找到了相关的配置参数,EMQX的官方参数解释或者支持真心跟不上,没有国外开源组织社区营造的好,这个需要努力。

2019-09-19 14:22:30.362[error] f2ac199b0314449d822e150c8d51de93 crasher:

initial call: emqx_session:init/1pid:<0.20141.1>registered_name: []

exception exit: killedin function emqx_session:handle_info/2 (src/emqx_session.erl, line 641)in call from gen_server:try_dispatch/4 (gen_server.erl, line 637)in call from gen_server:handle_msg/6 (gen_server.erl, line 711)

ancestors: [emqx_session_sup,emqx_sm_sup,emqx_sup,<0.1386.0>]

message_queue_len:0messages: []

links: [<0.1577.0>]

dictionary: [{force_shutdown_policy,

#{max_heap_size=> 838860800,message_queue_len => 8000}},

{deliver_stats,676193},

{'$logger_metadata$',

#{client_id=> <>}}]

trap_exit:truestatus: running

heap_size:6772stack_size:27reductions:69920965neighbours:

再看看emqx.conf的配置文件中,和这个queue相关的配置:

## Max message queue length and total heap size to force shutdown

## connection/session process.

## Message queue hereisthe Erlang process mailbox, but not the number

## of queued MQTT messages of QoS1 and 2.

##

## Numbers delimited by `|'. Zero or negative is to disable.

##

## Default:

##- 8000|800MB on ARCH_64 system

##- 1000|100MB on ARCH_32 sytem

## zone.external.force_shutdown_policy= 8000|800MB

有人会说,你可以将这里的消息数量调大点啊,没错,这个调一下是可以改善,但是不能根治问题,自己想想吧,大点最多也就是对消息速率波动的韧性加大了,但是不能解决持续生成高于所谓的消费慢这种情况下的问题。 EMQ方说辞其实,在我们的这个场景下,我是不那么认同的,为什么这么说呢, 我的规则引擎消费日志里面显示,每条消息处理的时间并没有变长,CPU的忙碌程度并没有恶化, 添加共享订阅实例变多,EMQX性能下降了,我觉得EMQX在共享订阅变多的情况下,对消费者端投递消息的速率或者效率下降了,但是呢,EMQX这个broker从消息生产者这边接收消息的能力没有改变,导致EMQX的消息队列消息积压,最终出现踢连接的policy得以执行。。。

还有一个问题,不知道细心的读者有没有发现,消费者这边消息消费的好好的,消息积压了,EMQX为何要把消费者的连接给踢掉呢,为何不是将生产者的连接踢掉呢?这个逻辑我觉得有点不是很好理解,本来消息就积压了,是不是要加快消费才能缓解或者解除消息积压的问题?读者你们是如何理解的,也可以留言探讨!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值