MQTT процесс обновления версии и решительность источник

MQTT процесс обновления версии и решительность источник


  Первые разговоры о том, почему пишу эту статью он, я нашел статью в интернете MQTT введена слишком мал, он может использовать эту сравнительно низкую частоту его! Существует проблема поиска и устранения путей и средств слишком мало, так что он написал эту статью в надежде внести свой вклад, чтобы помочь некоторым людям нуждающимся.

  Основная проблема MQTT записывайте, что появились в оригинальной версии 1.2.0 конечно, Устранение проблем, возникающих в процессе обновления версии 1.2.1, исходный код через шаг за шагом исследования и конечной точкой задачи, пока в соответствии с ожиданиями.

 

<! - https://mvnrepository.com/artifact/org.eclipse.paho/org.eclipse.paho.client.mqttv3 -> 
< зависимость > 
    < идентификатор_группы > org.eclipse.paho </ идентификатор_группы > 
    < артефакта > org.eclipse.paho.client.mqttv3 </ артефакта > 
    < версия > 1.2.1 </ версия > 
</ зависимость >

  MQTT строить и сертификат SSL может ссылаться на этот блог: https://www.cnblogs.com/yueli/p/7490453.html  не указано в этом тщательно


  введение Qos 

  В начале первого взгляда на смысл некоторых Qos, является проблемой для предохранителя

  • Qos = 0 до передачи

       Издатель ПУБЛИКОВАТЬ сообщение на сервере (брокер), то есть передача отбрасываются. Нет подтверждающее сообщение, я не знаю , принято ли другая сторона. Сетевой уровень, трансмиссия небольшое давление

  • Qos = 1, по меньшей мере одна передача

   Издатель объявил спасительное сообщение, сервер (брокер) получает сообщение, сервер (брокер) ПУБЛ на абонентском сервер (брокер) назад к информации PUBACK издателю LET удалить сообщение, то абонент после получения сообщения PUBACK на сервер , так что удаленный сообщения. Если это не удается, не подтвердили информации , полученной в течение определенного периода времени, то отправитель будет заголовок DUP устанавливается равным 1, а затем отправить сообщение еще раз, сообщение по крайней мере один раз , чтобы добраться до сервиса. Такие , как сетевые задержки и другие вопросы, издатель повторить , чтобы отправить сообщение, абоненты подписываются повторить сообщение несколько раз 

  • Qos = 2 только одна передача

  На самом деле, Qos = 2 просто сделал рывок , чтобы избавиться от стопы на основании 1, издатель ПУБЛИКОВАТЬ на сервер после более чем сообщение о подтверждении, и больше новостей MsgID кэша , чтобы повторить информации тяжелый. После того как сервер абонента ПУБЛИКОВАТЬ более чем сообщение с подтверждением.

  Разница между этими тремя случаями

   -Не сохраняется сообщением, нет механизма повторной передачи, не знает, что независимо от того, 1 и 2 издателя и сервер сохранил сообщение, издатель имеет механизм повторной передачи, подтверждение механизм PUBACK после того, как сервер ПУБЛИКАЦИИ, но сервер 2 множество кэш-функции MsgID, который обеспечивает функцию дедупликации, чтобы предотвратить повторную передачу сообщения, и полученное сообщение подтверждения механизма. Абоненты вводные здесь, но больше заинтересованы идти, чтобы понять.


 MQTT1.2.1 версия возникающие вопросы 

  Описание проблемы: потому что больше места, чтобы использовать коммуникационные проекты MQTT, как правило, в виде Qos = 0, на этот раз обнаружил, что всегда будет напоминать об ошибке Слишком много публикует в процессе (32202), место смотрел на ошибки исходного кода

   Здесь вы можете создать свое собственное суждение actualInFlight превышать максимально maxInflight, вызванными попытками увеличить maxInflight также бесполезно, но только время задержки ошибки


 процесс устранения неисправностей

  Первый поиск в Интернете , чтобы увидеть , если есть подобные проблемы, конечно же есть приятель встретил, адрес блога: https://blog.csdn.net/lblblblblzdx/article/details/81159478  эта статья дала мне большую помощь, благодаря блоггерам, но окончательное решение не очень хорошо.

  процесс выпуска логического трека Источника

  Первый шаг: процесс опубликовать

// 1 
общественного IMqttDeliveryToken публиковать (String тему, MqttMessage сообщение, UserContext Object, IMqttActionListener обратный вызов)
 // 2 
общественная  пустота sendNoWait (MqttWireMessage сообщение, MqttToken маркер)
 // 3 
аннулируются internalSend (MqttWireMessage сообщение, MqttToken маркер)
 // 4 
общественного  недействительными отправить (MqttWireMessage сообщение, MqttToken маркер)

  Шаг второй: Qos всех типов, сконфигурированный в родительском верхнем уровне публиковать сообщения по умолчанию настройка MsgID = 0  

  Третий шаг: сообщение из крупной сделки в методе отправки

   Шаг четвертый: Согласно описанию выше Qos, что мы публикуем новости этого места всех кэшированные жетонов здесь, на самом деле, помещенные в Hashtable, независимо от того, какого уровня Qos

   В этих шагов, хорошая новость уже кэшируются, готов к отправке асинхронно, в котором механизм блокировки не так много, чтобы объяснить

  Шаг пять: асинхронный посыл, это в основном в связи с клиентом до завершения, когда он начал слушать вверх, подключает поток

 1 //1
 2 public IMqttToken connect(MqttConnectOptions options)
 3 
 4 //2 异步链接
 5 ConnectActionListener connectActionListener = new ConnectActionListener(this, persistence, comms, options,userToken,userContext, callback, reconnecting);
 6 connectActionListener.connect();
 7 
 8 //3 客户端的通信链接,包括发送和接收
 9 ClientComms.connect(options, token);
10 
11 //4 个人理解是 将通信信息塞进线程池中,分别开启发送和接收的线程处理
12 ConnectBG conbg = new ConnectBG(this, token, connect, executorService);
13 conbg.start();

  第六步:在ConnectBG的run中 new CommsSender. start线程run中while循环发送的信息流程,一直发送消息中

 

   第七步:在notifySent的方法中判断Qos = 0 的作出了判断及操作

   这些差不多就是发布过程的主题流程结构,了解这些才会知道让你解决问题更加的容易


  问题点

  在上面的第六步的图中黄色箭头指出了问题出现的点,主要是在大数据量高并发的时候,因为在Qos = 0 的时候,在tokens(Hashtable)中的key一直是0,默认初始化。后面的流程中并没有改变过,在黄色那块tokenStore.getToken 在发送之后才remove数据,但是多条数据高并发的时候,在remove数据之后,后一条在get的时候会出现空的状况,不发送信息,导致actualInFlight没有减,一直增加,一定时间后就会超出最大值。Qos =1 、2 是不会发送这样的情况,因为他们的messageId是唯一的。


  解决办法

  1. 将Qos设置为1 (这是网上主流的解决办法,但是这个太耗费资源问题,在我看来只是规避问题点而已)
  2. 升级MQTT版本1.2.1    (这个版本解决了刚才说的bug)      
  3. 也可以想想在不升级版本的情况下如何去改善这个问题,重写那些类可以实现···

  


 

   解决过程

  既然说了第一种解决办法不是很赞同,那就直接进去第二种办法吧。升级到1.2.1版,时间:Feb, 2019,但是在升级版本的时候又出现了一些问题,因为改动还是有点多的。

  接下来说说1.2.1版本的改动了什么呢


  首先主要改动的是在Qos = 0 的不放入tokens中了,首先想到的是不会get到了,也不用担心重复了,直接从集合pendingMessages中拿

   然后从信息的自身获取数据的token,获取不到再去tokens中拿

    以上两个就是主要解决这个高并发冲突的原因


    跳入另一个坑中···

   为什么这么说呢,在我们开发的意识中,升级版本怎么也要向下兼容吧,那就顺其自然的换个版本就完事了,结果一跑起来,一堆红色的出现,那心情···我太南了。以我的性子,就是不能惯着她,继续深挖为什么,既然坑已经有了,就不怕有多深。

   另一个坑的过程

    第一时间也是上网搜一些为啥,大家的解决也差不多,都是SSL验证出现问题,但是解决方案也是五花八门


 

  解决方案

       第一种:设置系统属性  类似这样的文章 https://blog.csdn.net/hxpjava1/article/details/77937026

   第二种:有看了一些代码了,就是重写X509TrustManagerImpl,绕过SSL的验证,试过有用,类似这样的文章 https://blog.csdn.net/iverson_AL/article/details/100669777

   第三种:再深入看一些源码,你会看到会什么会报错,为什么会验证,主要是你的属性没有设置好,采用了默认验证导致


   解决过程

  这里主要说一下解决的过程,如何从这些网络文章种找出适合自己的出路。

  首先 第一种我就不咋喜欢,动不动就设置了系统全局属性,第二种方案,有两种可能性,一是这个api真的有问题或是不符合自己的项目需要重写代码逻辑结构,二是在不了解的情况下直接绕过验证。我在测试第二个的时候就是如此只是稍微看了一下源码,没有深入看进去,试了一下,果真可以实现我想要目的。

  但是过后又想了一下,不该如此,既然开源出来的东西,不可能如此**,应该会有什么地方可以简单设置一下的。既然有这个想法就一直深入探究下去,果不其然,真相出来了。

  在1.2.1版本中MqttConnectOptions 的httpsHostnameVerificationEnabled属性默认true,导致不是Https的被验证不通过导致的,也可能MQTT开发人员安全意识很强,在1.2.0版本中没有这个概念存在,所以在版本升级的时候需要加上MqttConnectOptions.setHttpsHostnameVerificationEnabled(false);

  以下源码查看的过程

    若是有Https证书是不会有问题的。


  总结一下

   其实很简单的问题,居然整的时候那么复杂,原因是我们不够强,面对源码的时候还是比较害怕的,还有比较懒吧。

   整个过程比较繁琐,啰嗦吧,耐心看下来,应该有收获。

   操作总结:

    1. 升级MQTT版本1.2.1
    2. 若不是https的需要设置为false
    3. 不要走,跑起来

   扩展点及疑惑地点可以供参考

  

 

              转载请注明出处  https://www.cnblogs.com/zhouguanglin/p/11986446.html

 

рекомендация

отwww.cnblogs.com/zhouguanglin/p/11986446.html