关于消息体转化导致客户端未连接

环境信息

  • EMQ X 版本:4.3.10
  • 操作系统及版本:centos7
  • 其他

问题描述

    private void deviceInfo(MqttMessage mqttMessage) {
        //添加设备信息
        IotDevice device = JSON.parseObject(new String(mqttMessage.getPayload()), IotDevice.class);

上面这个消息体 json 转化的时候如果失败,就会导致下面的异常一直循环发送,最终导致服务器崩溃!这个异常无法捕捉,请教下谁有什么好的方案吗?

12:39:18.964 [MQTT Ping: mqtt_client_e7aa5b095d939e8d659283d26950b06c] ERROR o.e.p.c.m.i.ClientState - [logToJsr47,210] - mqtt_client_e7aa5b095d939e8d659283d26950b06c: Timed out as no write activity, keepAlive=20,000,000,000 lastOutboundActivity=619,200,644,802,100 lastInboundActivity=619,200,655,607,800 time=619,782,713,292,200 lastPing=619,200,644,814,800
12:39:18.969 [MQTT Ping: mqtt_client_e7aa5b095d939e8d659283d26950b06c] ERROR c.s.s.m.c.MqttMessageCallback - [connectionLost,34] - 连接断开,正在尝试重新连接 >>>>>>>
12:39:18.969 [MQTT Ping: mqtt_client_e7aa5b095d939e8d659283d26950b06c] INFO  c.s.s.m.MqttOperateClient - [connect,69] - 【MQTT客户端正在初始化】MQTT client init ......host:tcp://localhost:1883,clientId:mqtt_client_e7aa5b095d939e8d659283d26950b06c
12:39:18.973 [MQTT Ping: mqtt_client_e7aa5b095d939e8d659283d26950b06c] INFO  c.s.s.m.MqttOperateClient - [connect,87] - 【MQTT客户端连接失败】MQTT client connected fail ✘......
MqttException (0) - java.net.NoRouteToHostException: No route to host: connect
    at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:738)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.NoRouteToHostException: No route to host: connect
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:81)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:162)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)
    at java.net.Socket.connect(Socket.java:606)
    at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:74)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:724)
    ... 1 more
客户机未连接 (32104)
    at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:31)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms.sendNoWait(ClientComms.java:205)
    at org.eclipse.paho.client.mqttv3.MqttAsyncClient.subscribeBase(MqttAsyncClient.java:1088)
    at org.eclipse.paho.client.mqttv3.MqttAsyncClient.subscribe(MqttAsyncClient.java:1152)
    at org.eclipse.paho.client.mqttv3.MqttClient.subscribe(MqttClient.java:459)
    at org.eclipse.paho.client.mqttv3.MqttClient.subscribe(MqttClient.java:429)
    at org.eclipse.paho.client.mqttv3.MqttClient.subscribe(MqttClient.java:422)
    at com.shanlomed.system.mqtt.MqttOperateClient.subscribe(MqttOperateClient.java:165)
    at com.shanlomed.system.mqtt.config.MqttConfig.getMqttOperateClient(MqttConfig.java:70)
    at com.shanlomed.system.mqtt.callback.MqttMessageCallback.connectionLost(MqttMessageCallback.java:37)
    at org.eclipse.paho.client.mqttv3.internal.CommsCallback.connectionLost(CommsCallback.java:304)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms.shutdownConnection(ClientComms.java:441)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms.handleRunException(ClientComms.java:838)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms.checkForActivity(ClientComms.java:820)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms.checkForActivity(ClientComms.java:804)
    at org.eclipse.paho.client.mqttv3.TimerPingSender$PingTask.run(TimerPingSender.java:79)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
客户机未连接 (32104)

首先是你的设备连接失败了,这个不会导致EMQX服务端挂的,你要看下 JSON.parseObject 的返回值是否符合预期

这个 JSON.parseObject 的返回值是本身是约定好的,但是有可能会产生不符合预期的情况,一旦发生,mqtt客户端就会不断地抛出客户端未连接的异常,服务器也就会不停的抛出以下问题:


2021-12-08T16:02:39.266146+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:49978 [CM] more_than_one_channel_found: [<0.16761.4>,<0.16429.4>]

2021-12-08T16:02:39.582577+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52252 [CM] more_than_one_channel_found: [<0.17023.4>,<0.17002.4>]

2021-12-08T16:02:39.609401+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52317 [CM] more_than_one_channel_found: [<0.17107.4>,<0.17097.4>]

2021-12-08T16:02:39.622301+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:63806 [CM] more_than_one_channel_found: [<0.17112.4>,<0.17124.4>]

2021-12-08T16:02:39.622951+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52380 [CM] more_than_one_channel_found: [<0.17124.4>,<0.17165.4>]

2021-12-08T16:02:39.667412+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52515 [CM] more_than_one_channel_found: [<0.17225.4>,<0.17215.4>]

2021-12-08T16:02:39.667977+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:63908 [CM] more_than_one_channel_found: [<0.17215.4>,<0.17231.4>]

2021-12-08T16:02:39.668446+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:63854 [CM] more_than_one_channel_found: [<0.17231.4>,<0.17203.4>]

2021-12-08T16:02:39.849611+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52625 [CM] more_than_one_channel_found: [<0.17289.4>,<0.17295.4>]

2021-12-08T16:02:39.851831+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52672 [CM] more_than_one_channel_found: [<0.17315.4>,<0.17313.4>]

2021-12-08T16:02:39.854657+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52729 [CM] more_than_one_channel_found: [<0.17342.4>,<0.17327.4>]

2021-12-08T16:02:39.865798+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52863 [CM] more_than_one_channel_found: [<0.17457.4>,<0.17481.4>]

2021-12-08T16:02:39.868445+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52885 [CM] more_than_one_channel_found: [<0.17452.4>,<0.17503.4>]

2021-12-08T16:02:39.871257+08:00 [error] mqtt_client_bce9e501c17ae8c861b1cb8b6c1c367b@x.x.x.x:52891 [CM] more_than_one_channel_found: [<0.17507.4>,<0.17516.4>]

这个是终端业务失败导致的,终端业务break之后TCP没有断开,然后尝试重新登陆,broker检测到上个TCP的session还在,这是把上一个踢掉的日志。EMQ X 的业务是正常的,也不会影响别的设备。至于你的客户端业务,只能自己catch处理一下,broker没有办法干预设备行为,更不能解决你的代码实现逻辑上的问题。

嗯嗯,是这么回事,我这边已经做了chatch处理了,谢谢!