Введение в MQTT QoS 0, 1, 2
Что такое качество обслуживания
В нестабильных сетевых средах устройства MQTT могут с трудом обеспечивать надежную связь, используя только транспортный протокол TCP. Чтобы решить эту проблему, MQTT включает в себя механизм качества обслуживания (QoS), который предлагает различные варианты взаимодействия сообщений для обеспечения различных уровней обслуживания, удовлетворяя особые требования пользователя к надежной доставке сообщений в различных сценариях.
В MQTT есть 3 уровня QoS:
- QoS 0, максимум один раз.
- QoS 1, хотя бы один раз.
- QoS 2, ровно один раз.
Эти уровни соответствуют возрастающим уровням надежности доставки сообщений. QoS 0 может привести к потере сообщений, QoS 1 гарантирует доставку сообщений, но потенциально может существовать дублирование сообщений, а QoS 2 гарантирует, что сообщения доставляются ровно один раз без дублирования. По мере повышения уровня QoS надежность доставки сообщений также увеличивается, но вместе с этим увеличивается и сложность процесса передачи.
В процессе доставки от издателя к подписчику издатель указывает уровень QoS сообщения в пакете PUBLISH. Брокер обычно пересылает сообщение подписчику с таким же уровнем QoS. Однако в некоторых случаях требования абонента могут потребовать снижения уровня QoS пересылаемого сообщения.
Например, если подписчик указывает, что он хочет получать только сообщения с уровнем QoS 1 или ниже, брокер понизит все сообщения с QoS 2 до QoS 1 перед их пересылкой этому подписчику. Сообщения с QoS 0 и QoS 1 будут передаваться абоненту с неизменными исходными уровнями QoS.
Давайте посмотрим, как работает QoS.
QoS 0 — не более одного раза
QoS 0 — это самый низкий уровень обслуживания, также известный как «запусти и забудь». В этом режиме отправитель не ждет подтверждения, не сохраняет и не ретранслирует сообщение, поэтому получателю не нужно беспокоиться о получении дубликатов сообщений.
Почему сообщения QoS 0 теряются?
Надежность передачи сообщения QoS 0 зависит от стабильности TCP-соединения. Если соединение стабильно, TCP может обеспечить успешную доставку сообщений. Однако, если соединение закрывается или сбрасывается, существует риск того, что сообщения в пути или сообщения в буфере операционной системы могут быть потеряны, что приведет к неудачной доставке сообщений QoS 0.
QoS 1 — хотя бы один раз
Для обеспечения доставки сообщений QoS 1 вводит механизм подтверждения и повторной передачи. Когда отправитель получает пакет PUBACK от получателя, он считает, что сообщение доставлено успешно. До тех пор отправитель должен сохранить пакет PUBLISH для возможной повторной передачи.
Отправитель использует идентификатор пакета в каждом пакете, чтобы сопоставить пакет PUBLISH с соответствующим пакетом PUBACK. Это позволяет отправителю идентифицировать и удалить правильный пакет PUBLISH из своего кэша.
Почему сообщения QoS 1 дублируются?
Есть два случая, когда отправитель не получит пакет PUBACK.
- Пакет PUBLISH не дошел до получателя.
- Пакет PUBLISH достиг получателя, но пакет PUBACK получателя еще не получен отправителем.
В первом случае отправитель повторно передаст пакет PUBLISH, но получатель получит сообщение только один раз.
Во втором случае отправитель повторно передаст пакет PUBLISH, а получатель получит его снова, что приведет к дублированию сообщения.
Несмотря на то, что флаг DUP в повторно переданном пакете PUBLISH установлен в 1, чтобы указать, что это дублирующее сообщение, получатель не может предположить, что он уже получил сообщение, и все равно должен рассматривать его как новое сообщение.
Это связано с тем, что есть два возможных сценария, когда получатель получает пакет PUBLISH с флагом DUP, равным 1:
В первом случае отправитель повторно передает пакет PUBLISH, поскольку он не получил пакет PUBACK. Получатель получает два пакета PUBLISH с одним и тем же идентификатором пакета, а второй пакет PUBLISH имеет флаг DUP, равный 1. Второй пакет действительно является дублирующим сообщением.
Во втором случае исходный пакет PUBLISH был успешно доставлен. Затем этот идентификатор пакета используется для нового несвязанного сообщения. Но это новое сообщение не было успешно доставлено узлу при первой отправке, поэтому оно было передано повторно. Наконец, повторно переданный пакет PUBLISH будет иметь тот же идентификатор пакета и флаг DUP, равный 1, но это будет новое сообщение.
Поскольку различить эти два случая невозможно, получатель должен рассматривать все пакеты PUBLISH с флагом DUP, равным 1, как новые сообщения. Это означает, что дублирование сообщений на уровне протокола неизбежно при использовании QoS 1.
В редких случаях брокер может получить дубликаты пакетов PUBLISH от издателя и в процессе их пересылки подписчику повторно передать их повторно. Это может привести к тому, что подписчик получит дополнительные повторяющиеся сообщения.
Например, хотя издатель отправляет только одно сообщение, получатель может в конечном итоге получить три идентичных сообщения.
Это недостатки использования QoS 1.
QoS 2 — ровно один раз
QoS 2 гарантирует, что сообщения не будут потеряны или дублированы, в отличие от QoS 0 и 1. Однако оно также имеет самые сложные взаимодействия и самые высокие накладные расходы, поскольку требует как минимум двух потоков запросов/ответов между отправителем и получателем для каждого сообщения. доставка.
- Чтобы инициировать передачу сообщения QoS 2, отправитель сначала сохраняет и отправляет пакет PUBLISH с QoS 2, а затем ожидает ответного пакета PUBREC от получателя. Этот процесс аналогичен QoS 1, за исключением того, что ответный пакет — PUBREC, а не PUBACK.
- Получив пакет PUBREC, отправитель может подтвердить, что пакет PUBLISH был получен получателем, и может удалить его локально сохраненную копию. Это больше не нуждается и не может ретранслировать этот пакет. Затем отправитель отправляет пакет PUBREL, чтобы сообщить получателю, что он готов выпустить идентификатор пакета. Как и пакет PUBLISH, пакет PUBREL должен быть надежно доставлен получателю, поэтому он сохраняется для возможной повторной передачи, и требуется ответный пакет.
- Когда получатель получает пакет PUBREL, он может подтвердить, что в этом потоке передачи не будут получены дополнительные повторно переданные пакеты PUBLISH. В результате получатель отвечает пакетом PUBCOMP, чтобы сигнализировать о том, что он готов повторно использовать текущий идентификатор пакета для нового сообщения.
- Когда отправитель получает пакет PUBCOMP, поток QoS 2 завершается. Затем отправитель может отправить новое сообщение с текущим идентификатором пакета, которое получатель будет рассматривать как новое сообщение.
Почему сообщения QoS 2 не дублируются?
Механизмы, используемые для гарантии того, что сообщения QoS 2 не будут потеряны, аналогичны механизмам, используемым для QoS 1, поэтому здесь они не будут обсуждаться снова.
По сравнению с QoS 1, QoS 2 гарантирует, что сообщения не будут дублироваться, путем добавления нового процесса, включающего пакеты PUBREL и PUBCOMP.
Прежде чем двигаться дальше, давайте кратко рассмотрим причины, по которым QoS 1 не может избежать дублирования сообщений.
Когда мы используем QoS 1, для получателя идентификатор пакета снова становится доступным после отправки пакета PUBACK, независимо от того, дошел ли ответ до отправителя. Это означает, что получатель не может определить, является ли пакет PUBLISH, который он получает позже, с тем же идентификатором пакета, повторной передачей от отправителя из-за того, что он не получил ответ PUBACK, или отправитель повторно использовал идентификатор пакета для отправки нового сообщения после получение ответа PUBACK. Вот почему QoS 1 не может избежать дублирования сообщений.
В QoS 2 отправитель и получатель используют пакеты PUBREL и PUBCOMP для синхронизации выпуска идентификаторов пакетов, обеспечивая консенсус в отношении того, повторно ли отправитель передает сообщение или отправляет новое. Это ключ к тому, чтобы избежать проблемы дублирования сообщений, которая может возникнуть в QoS 1.
В QoS 2 отправителю разрешено повторно передавать пакет PUBLISH перед получением пакета PUBREC от получателя. Как только отправитель получает PUBREC и отправляет пакет PUBREL, он вступает в процесс выпуска идентификатора пакета. Отправитель не может повторно передать пакет PUBLISH или отправить новое сообщение с текущим идентификатором пакета, пока не получит пакет PUBCOMP от получателя.
В результате получатель может использовать пакет PUBREL в качестве границы и рассматривать любой пакет PUBLISH, пришедший до него, как дубликат, а любой пакет PUBLISH, пришедший после него, как новый. Это позволяет избежать дублирования сообщений на уровне протокола при использовании QoS 2.
Сценарии и соображения
качество обслуживания 0
Основным недостатком QoS 0 является то, что сообщения могут быть потеряны в зависимости от условий сети. Это означает, что вы можете пропустить сообщения, если вы отключены. Однако преимущество QoS 0 заключается в том, что оно более эффективно для доставки сообщений.
Поэтому он часто используется для отправки высокочастотных, менее важных данных, таких как периодические обновления датчиков, когда допустимо пропустить несколько обновлений.
качество обслуживания 1
QoS 1 гарантирует, что сообщения будут доставлены хотя бы один раз, но это может привести к дублированию сообщений. Это делает его подходящим для передачи важных данных, таких как критические инструкции или обновления важного статуса в режиме реального времени. Однако важно рассмотреть, как обрабатывать или разрешать такое дублирование, прежде чем принимать решение об использовании QoS 1 без дедупликации.
Например, если издатель отправляет сообщения в порядке 1, 2, а подписчик получает их в порядке 1, 2, 1, 2, где 1 представляет команду включить свет, а 2 представляет команду его выключения. , может быть нежелательно, чтобы свет неоднократно включался и выключался из-за повторяющихся сообщений.
качество обслуживания 2
QoS 2 гарантирует, что сообщения не будут потеряны или дублированы. Однако он также имеет самые высокие накладные расходы. Если пользователи не хотят самостоятельно обрабатывать дублирование сообщений и могут согласиться с дополнительными издержками QoS 2, то это подходящий выбор. QoS 2 часто используется в таких отраслях, как финансы и авиация, где критически важно обеспечить надежную доставку сообщений и избежать дублирования.
вопросы и ответы
Как дедуплицировать сообщения QoS 1?
Поскольку дублирование сообщений QoS 1 заложено на уровне протокола, мы можем решить эту проблему только на уровне бизнеса.
Одним из способов дедупликации сообщений QoS 1 является включение метки времени или монотонно увеличивающегося счетчика в полезную нагрузку каждого пакета PUBLISH. Это позволяет вам определить, является ли текущее сообщение новым, сравнивая его метку времени или количество с меткой времени последнего полученного сообщения.
Когда следует пересылать сообщения QoS 2 подписчикам?
Как мы узнали, QoS 2 имеет высокие накладные расходы. Чтобы избежать влияния на характер сообщений QoS 2 в реальном времени, лучше всего инициировать процесс их пересылки подписчикам при первом получении пакета QoS 2 PUBLISH. Однако, как только этот процесс был инициирован, последующие пакеты PUBLISH, которые прибывают до пакета PUBREL, не должны перенаправляться снова, чтобы предотвратить дублирование сообщений.
Есть ли разница в производительности между QoS?
QoS 0 и QoS 1 обычно имеют одинаковую пропускную способность при использовании EMQX с одинаковой конфигурацией оборудования для одноранговой связи, но QoS 1 может иметь более высокую загрузку ЦП. Кроме того, при высокой нагрузке QoS 1 имеет большую задержку сообщений по сравнению с QoS 0. С другой стороны, QoS 2 обычно имеет только половину пропускной способности по сравнению с QoS 0 и 1.
Заключение
К настоящему моменту вы должны иметь полное представление о MQTT QoS. Чтобы продолжить изучение MQTT, вы можете ознакомиться с EMQ Начало работы с MQTT и дополнительные возможности серии, которые охватывают такие темы, как подстановочные знаки, сохраненные сообщения и сообщения завещания. Эти ресурсы помогут вам глубже изучить MQTT и разработать расширенные приложения и службы MQTT.
Первоначально опубликовано на https://www.emqx.com.