Изменения в QoS 1 и 2 в MQTT 5

#mqtt

Вопрос:

Согласно сайту HiveMQ здесь: https://www.hivemq.com/blog/mqtt5-essentials-part2-foundational-changes-in-the-protocol/ большая разница между QoS1 и 2 в версии 5 заключается в том, что «для исправного соединения повторная попытка невозможна» для сообщений, которые не поступают в пункт назначения. Я не уверен в следующем пункте:

  • Я просмотрел стандарт, я не нашел никаких упоминаний об этом, может ли кто-нибудь подтвердить, что это правда?
  • Означает ли это, что если соединение прервется, пока сообщения находятся в полете, или сообщения не будут подтверждены, потому что получатель недоступен, это единственный случай, когда будет повторная передача?
  • Как насчет перегрузки сети, но PINGREQ/PINGRES все еще работают?

Спасибо!

Ответ №1:

Спецификация V5 гласит:

Когда Клиент повторно подключается с установленным значением «Чистый запуск» 0 и присутствует сеанс, и Клиент, и Сервер ДОЛЖНЫ повторно отправлять любые неподтвержденные пакеты ПУБЛИКАЦИИ (где QoS > 0) и пакеты PUBREL, используя их исходные идентификаторы пакетов. Это единственное обстоятельство, при котором Клиенту или Серверу ТРЕБУЕТСЯ повторно отправлять сообщения. Клиенты и серверы НЕ ДОЛЖНЫ повторно отправлять сообщения в любое другое время [MQTT-4.4.0-1].

«НЕ ДОЛЖНО» — это изменение спецификации V3 (которая разрешала повторную отправку, но не требовала этого). Я считаю, что это отвечает на ваш второй вопрос (в спецификации довольно ясно, что сообщения не должны быть отправлены иначе, как после повторного подключения).

Как насчет перегрузки сети, но PINGREQ/PINGRES все еще работают?

Когда a PINGREQ будет получено, a PINGRESP будет отправлено; если перегрузка сети помешает доставке в течение разрешенного периода времени, соединение будет прервано; в противном случае оно не будет работать. TCP обеспечивает гарантию доставки пакетов в порядке, поэтому в конечном итоге сообщения должны пройти (я понимаю, что это не всегда работает на 100%).

Я не могу сказать, почему это изменение было внесено в спецификацию v5, но в статье, которую вы читаете, говорится:

На практике это очень плохая идея, так как перегруженные клиенты MQTT могут быть перегружены еще больше.

Mosquitto прекратил поддержку повторных попыток в версии 1.5 по следующим причинам:

Исходящие сообщения с QoS>1 больше не повторяются по истечении времени ожидания. Сообщения будут повторяться при повторном подключении клиента. Это изменение в поведении может быть оправдано, если учесть, когда мог произойти тайм-аут.

  • Если соединение ненадежно и прервано, но никто не заметил этого, сообщения будут повторены при повторном подключении. Отправка дополнительной ПУБЛИКАЦИИ или публикации ничего бы не изменила.
  • Если клиент перегружен/не может ответить/имеет медленное соединение, то отправка дополнительной ПУБЛИКАЦИИ или публикации не поможет клиенту наверстать упущенное. Как только отставание будет устранено, клиент ответит. Если он не сможет догнать, отправка дополнительных дубликатов также не поможет.

Комментарии:

1. это полностью отвечает на мои вопросы, такс!

2. думая о it…it похоже, что теперь нет большой разницы между QoS 1 и 2, поскольку любая повторная передача должна подразумевать повторное соединение, или я ошибаюсь? Если только многолучевость не может вызвать задержки и все еще возможно получать повторяющиеся сообщения после отключения, в этом случае это все еще имело бы смысл….

3. Каждый раз, когда сообщение негодует, существует вероятность дублирования; QOS 2 позволяет избежать этого, используя рукопожатие из четырех частей. Отказ от повторной отправки сообщений по таймеру снижает, но не устраняет вероятность того, что это произойдет в первую очередь. Частично обработанные сообщения являются частью сеанса, поэтому после повторного подключения с помощью CleanSession=false они будут возмущены.