mqtt客户端连接Emq服务器,断开重连的connect 一直超时等待

背景:当我们的设备更新完成,大量的设备重新连接到EMQ,导致EMQ 的cpu直接到100%,此时

错误日志: 

 info日志

 在上述两张日志中,可以发现我publish消息时,错误日志为“客户端未连接”,但是在下面的info中,却发现在2毫秒后,仍然又receiver,那么客户端应该连接了。

背景:

那么真正的问题是,短时间内大量client连接到EMQ,导致EMQ的cpu达到100%,是的EMQ与我的服务器断开连接,服务器走断开重连,却一直没有走完client 连接 broker 的整个连接,所以我的服务器陷入了一直等待。

bug原因

先修知识:

心跳机制:

keep Alive 指定连接最大空闲时间T,当客户端检测道连接空闲时间超过T时,必须向Borker发送心跳报文PINGREQ, Broker收到心跳请求后返回心跳响应PINGRESP.若Broker超过1.5T时间没手法哦心跳请求则断开连接,并且投递遗嘱消息到订阅者,同样,若客户端超过一定时间仍没有收到心跳响应PINGRESP则断开连接。

(一)、为什么在EMQ压力大的时候,client 会与EMQ 断开连接??

EMQ与我的服务器有一个心跳机制,通过这个心跳机制来检测client与broker是否正常连接,在一定时间内心跳检测失败,则断开连接。EMQ因为cpu到大100%,消息处理不了,则对服务器的心跳PINGREQ,一直没有PINGRESP 回复,则EMQ提出client,服务器断开重连。

MQTT底层源码解析
1. mqtt 源码底层有一个心跳协议,起了一个pingTask的任务一直检测心跳活性 

private class PingTask extends TimerTask {
		private static final String methodName = "PingTask.run";
		
		public void run() {
			//@Trace 660=Check schedule at {0}
			log.fine(CLASS_NAME, methodName, "660", new Object[]{Long.valueOf(System.nanoTime())});
			comms.checkForActivity();	//检测心跳活性		
		}
	}

2.通过心跳协议,检测当前客户端活性 

public MqttToken checkForActivity(){              
	return this.checkForActivity(null);           
}                                                 

public MqttToken checkForActivity(IMqttActionListener pingCallback){ 
	MqttToken token = null;                                          
	try{                                                             
		token = clientState.checkForActivity(pingCallback); //检测心跳超时等待         
	}catch(MqttException e){                                         
		handleRunException(e);                                       
	}catch(Exception e){                                             
		handleRunException(e);                                       
	}                                                                
	return token;                                                    
}	                                                                 

3检测心跳超时等待

        long nextPingTime = this.keepAlive;
		
		if (connected && this.keepAlive > 0) {

			long time = System.nanoTime();
			
			int delta = 100000;
			
            synchronized (pingOutstandingLock) {                                                                                                                           
               if (pingOutstanding > 0 && (time - lastInboundActivity >= keepAlive + delta)) {
                                              
               ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_TIMEOUT);
                }

 (二)、为什么我们的服务器会在重连EMQ时,一直卡在Connect??

MQTT客户端与EMQ主机连接过程如图所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值