Предисловие

QUIC (RFC9000) — это базовый транспортный протокол интернет-протокола следующего поколения HTTP/3. По сравнению с протоколами TCP/TLS он обеспечивает эффективный и гибкий транспортный уровень для мобильного Интернета, который снижает нагрузку на сеть и задержку при обмене сообщениями.

EMQX 5.0 — это первый инновационный продукт, который представляет QUIC для MQTT. Мы обнаружили, что функции QUIC идеально подходят для некоторых сценариев в IoT, когда мы поддерживали клиентов и разрабатывали технологии, поэтому мы попытались заменить транспортный уровень MQTT на QUIC, что привело к MQTT поверх QUIC.

Как описано в предыдущей статье, QUIC обладает низкими сетевыми издержками и возможностью мультиплексирования, что дает ему большое преимущество в сценариях IoT, где сети нестабильны и соединения часто переключаются. Данные испытаний показывают, что MQTT по сравнению с QUIC может эффективно улучшить работу пользователя в нестабильных сетях со слабыми сигналами и нестабильными соединениями благодаря возможности QUIC: 0 RTT/1 RTT переподключение/новое.

Являясь Основным спонсором OASIS, всемирно известной организации с открытым исходным кодом и открытыми стандартами, EMQ активно поддерживает стандартизацию MQTT по сравнению с QUIC. Некоторые клиенты уже пытались использовать эту новую функцию, и мы получили хорошие отзывы. Эта статья поможет вам приступить к изучению функции MQTT Over QUIC в EMQX 5.0.

Включить MQTT через QUIC

MQTT через QUIC поддерживается начиная с EMQX 5.0.

Это экспериментальная функция. Для CentOS 6, macOS и Windows вам необходимо скомпилировать QUIC из исходного кода. Пожалуйста, установите BUILD_WITH_QUIC=1 во время компиляции.

MQTT через QUIC по умолчанию отключен. Вы можете включить его вручную, выполнив следующие действия.

  1. Откройте файл конфигурации etc/emqx.conf и раскомментируйте блок listeners.quic.default (добавьте его вручную, если он не существует):
# etc/emqx.conf
listeners.quic.default {
  enabled = true
  bind = "0.0.0.0:14567"
  max_connections = 1024000
  keyfile = "etc/certs/key.pem"
  certfile = "etc/certs/cert.pem"
}

2. Эта конфигурация включает прослушиватель QUIC на порту UDP 14567. После успешного сохранения перезапустите EMQX, чтобы активировать конфигурацию.

Вы также можете включить функцию QUIC с помощью env vars при запуске EMQX:

EMQX_LISTENERS__QUIC__DEFAULT__keyfile="etc/certs/key.pem" \
EMQX_LISTENERS__QUIC__DEFAULT__certfile="etc/certs/cert.pem" \
EMQX_LISTENERS__QUIC__DEFAULT__ENABLED=true

3. Использует команду emqx_ctl listeners для просмотра состояния прослушивателя QUIC:

> emqx_ctl listeners
quic:default
listen_on       : :14567
acceptors       : 16
proxy_protocol : undefined
running         : true
ssl:default
listen_on       : 0.0.0.0:8883
acceptors       : 16
proxy_protocol : false
running         : true
current_conn   : 0
max_conns       : 512000

Вы также можете использовать Docker для быстрой работы, установив UDP-порт 14567 в качестве порта QUIC через переменную среды:

docker run -d --name emqx \
-p 1883:1883 -p 8083:8083 \
-p 8084:8084 -p 8883:8883 \
-p 18083:18083 \
-p 14567:14567/udp \
-e EMQX_LISTENERS__QUIC__DEFAULT__keyfile="etc/certs/key.pem" \
-e EMQX_LISTENERS__QUIC__DEFAULT__certfile="etc/certs/cert.pem" \
-e EMQX_LISTENERS__QUIC__DEFAULT__ENABLED=true \
emqx/emqx:5.0.10

Клиенты и инструменты для MQTT через QUIC

Клиенты и инструменты для MQTT через QUIC не являются полнофункциональными, как обычный клиент MQTT.

На основе сценариев, подходящих для MQTT, мы планируем предоставлять клиенты на нескольких языках, таких как C, Java, Python и Golang. Эти клиенты будут разрабатываться в приоритетном порядке, чтобы соответствующие сценарии, такие как встроенное оборудование, могли как можно быстрее воспользоваться преимуществами QUIC.

Доступные клиентские SDK

  • NanoSDK: MQTT SDK на основе C, выпущенный командой NanoMQ в EMQ. Помимо MQTT через QUIC, он также поддерживает другие протоколы, такие как WebSocket и nanomsg/SP.
  • NanoSDK-Python: привязка NanoSDK к Python.
  • NanoSDK-Java: привязка Java JNA к NanoSDK.
  • emqtt: клиентская библиотека MQTT, разработанная на Erlang, поддерживающая QUIC.

В дополнение к клиентской библиотеке EMQ предоставляет возможность соединения MQTT с QUIC в продукте граничных вычислений NanoMQ. NanoMQ можно использовать для передачи данных с периферии в облако через QUIC, чтобы MQTT поверх QUIC можно было использовать без кодирования.

Проблемы и решения

Многие операторы связи имеют специальные сетевые правила для пакетов из UDP, что может привести к сбою подключения к QUIC или отбрасыванию пакетов, поскольку QUIC основан на UDP.

Таким образом, клиент MQTT поверх QUIC разработан с возможностью отката: вы можете разрабатывать сервисы через унифицированные API, а транспортный уровень можно изменять в режиме реального времени в зависимости от состояния сети. Если QUIC недоступен, он автоматически переключается на TCP/TLS 1.2, чтобы обеспечить правильное использование служб в разных сетях.

Подключить MQTT через QUIC через NanoSDK

NanoSDK основан на проекте MsQuic. Это первый SDK для MQTT поверх QUIC на C, и он полностью совместим с EMQX 5.0. Ключевые особенности NanoSDK включают в себя: асинхронный ввод-вывод, сопоставление соединения MQTT с потоком QUIC, рукопожатие 0RTT с малой задержкой и параллельную обработку нескольких ядер.

Примеры NanoSDK

API следует тому же стилю, что и предыдущий. Создать клиент MQTT на основе QUIC можно одной строкой кода:

## Create MQTT over Quic client with NanoSDK
nng_mqtt_quic_client_open(&socket, url);

Пример кода см. по адресу: https://github.com/nanomq/NanoSDK/tree/main/demo/quic.

После завершения компиляции вы сможете запустить приведенную ниже команду, чтобы подключиться к порту 14567 для тестирования.

quic_client sub/pub mqtt-quic://54.75.171.11:14567 topic msg

NanoSDK также обеспечивает привязку Java и Python. См. примеры: MqttQuicClient.java и mqttsub.py.

Мост MQTT 3.1.1/5.0 и MQTT через QUIC через NanoMQ

NanoMQ — сверхлегкий, высокопроизводительный и кроссплатформенный MQTT-брокер для периферии IoT. Его можно использовать в качестве шины сообщений для многих протоколов, и он может соединять MQTT и MQTT через QUIC. Он передает пакеты MQTT по протоколу QUIC, которые отправляются на EMQX в облаке. Таким образом, граничные устройства, которые не могут быть интегрированы с MQTT через QUIC SDK или не могут найти соответствующий MQTT через QUIC SDK, а также встроенные устройства, прошивка которых не может быть изменена, могут использовать преимущества протокола QUIC в сценариях IoT. Это будет очень удобно для пользователя.

Поскольку NanoMQ может обрабатывать множество протоколов, он очень полезен в сценариях IoT, где данные синхронизируются с облачными службами. Его можно использовать в качестве шины сообщений и системы хранения для распространенных протоколов обмена сообщениями через брокера и без брокера, таких как HTTP, MQTT 3.1.1/5.0, WebSocket, nanomsg/nng и ZeroMQ. «Актор» NanoMQ, мощная и встроенная модель обработки сообщений, преобразует данные этих протоколов в стандартные сообщения из протокола MQTT, и они отправляются в Облако через QUIC.

Это полностью использует возможности MQTT через QUIC, такие как быстрое переподключение 0RTT и пассивное переключение адресов, для решения общих проблем в соединении IoT, таких как сетевой роуминг, слабая передача сетей и блокировка очереди ПТС. Вы также можете перенаправлять, кэшировать или сохранять данные с помощью Rule Engine NanoMQ.

Благодаря архитектуре обмена сообщениями Cloud-Edge EMQX+NanoMQ пользователи могут быстро и дешево собирать и синхронизировать данные в любое время и в любом месте в сценариях Pan IoT.

Стоит отметить, что NanoMQ может автоматически переключаться на стандартный MQTT через TCP/TLS при сбое соединения QUIC, чтобы сетевое окружение не повлияло на ваше устройство.

Пример моста NanoMQ

Загрузите и установите NanoMQ:

git clone https://github.com/emqx/nanomq.git
cd nanomq ; git submodule update --init --recursive

mkdir build && cd build
cmake -G Ninja -DNNG_ENABLE_QUIC=ON ..
sudo ninja install

После компиляции и установки NanoMQ, поддерживающего QUIC, вы можете настроить MQTT поверх QUIC и связанные темы в файле конфигурации /etc/nanomq.conf. Использование mqtt-quic в качестве префикса URL означает использование QUIC в качестве транспортного уровня для MQTT:

## Bridge address: host:port .
##
## Value: String
## Example: ## Example: mqtt-tcp://broker.emqx.io:1883 (This is standard MQTT over TCP)
bridge.mqtt.emqx.address=mqtt-quic://54.75.171.11:14567

MQTT поверх инструментов QUIC CLI

NanoMQ также предоставляет nanomq_cli, который содержит клиентские инструменты для MQTT через QUIC, чтобы пользователи могли тестировать MQTT через QUIC EMQX 5.0:

nanomq_cli quic --help
Usage: quic conn <url>
       quic sub  <url> <qos> <topic>
       quic pub  <url> <qos> <topic> <data>

## subscribe example
nanomq_cli quic sub mqtt-quic://54.75.171.11:14567 2 msg

В заключение, вы можете интегрировать NanoSDK непосредственно в свои проекты или использовать клиентские инструменты, оба из которых могут подключать устройства к облаку через QUIC.

Используйте emqtt-bench для тестирования производительности QUIC

emqtt-bench — это инструмент для тестирования производительности MQTT, который поддерживает QUIC. Мы использовали его для проведения теста производительности MQTT over QUIC vs TCP/TLS. Его можно использовать для тестирования приложений или проверки производительности и преимуществ MQTT по сравнению с QUIC в реальных условиях.

Скомпилируйте emqtt-bench

Для компиляции требуется Erlang. Возьмем, к примеру, macOS для установки Erlang и Coreutils:

brew install coreutils
brew install erlang@24

Скомпилируйте emqtt-bench из исходников

git clone https://github.com/emqx/emqtt-bench.git
cd emqtt-bench
CMAKE_BUILD_TYPE=Debug BUILD_WITH_QUIC=1 make

Следующие подсказки отображаются для успешной компиляции:

...
===> Warnings generating release:
*WARNING* Missing application sasl. Can not upgrade with this release
===> Release successfully assembled: _build/emqtt_bench/rel/emqtt_bench
===> Building release tarball emqtt_bench-0.3+build.193.ref249f7f8.tar.gz...
===> Tarball successfully created: _build/emqtt_bench/rel/emqtt_bench/emqtt_bench-0.3+build.193.ref249f7f8.tar.gz

Могут возникнуть следующие ошибки, которые можно игнорировать:

/Users/patilso/emqtt-bench/scripts/rename-package.sh: line 9: gsed: command not found
/Users/patilso/emqtt-bench/scripts/rename-package.sh: line 9: gsed: command not found
/Users/patilso/emqtt-bench/scripts/rename-package.sh: line 9: gsed: command not found
/Users/patilso/emqtt-bench/scripts/rename-package.sh: line 9: gsed: command not found

Тест QUIC

Перейдите в выходной каталог компиляции:

cd _build/emqtt_bench/rel/emqtt_bench/bin

Вы можете использовать QUIC через опцию — quic для инициации соединения и подписки, здесь 10 клиентов подписываются на топик t/1.

./emqtt_bench sub -p 14567 --quic -t t/1 -c 10

Откройте новое окно, а также используйте QUIC для подключения и тестирования файла Publish.

./emqtt_bench pub -p 14567 --quic -t t/1 -c 1

Тест производительности будет проведен для «1 pub 10 sub»:

Проверьте использование локального UDP-порта 14567:

$ lsof -nP -iUDP | grep 14567

com.docke 29372 emqx   76u  IPv6 0xea2092701c033ba9      0t0  UDP *:14567
beam.smp  50496 emqx   39u  IPv6 0xea2092701c014eb9      0t0  UDP [::1]:52335->[::1]:14567
beam.smp  50496 emqx   40u  IPv6 0xea2092701c017689      0t0  UDP [::1]:56709->[::1]:14567
beam.smp  50496 emqx   41u  IPv6 0xea2092701c0151c9      0t0  UDP [::1]:52175->[::1]:14567
beam.smp  50496 emqx   42u  IPv6 0xea2092701c0157e9      0t0  UDP [::1]:54050->[::1]:14567
beam.smp  50496 emqx   43u  IPv6 0xea2092701c015af9      0t0  UDP [::1]:58548->[::1]:14567
beam.smp  50496 emqx   44u  IPv6 0xea2092701c013639      0t0  UDP [::1]:52819->[::1]:14567
beam.smp  50496 emqx   45u  IPv6 0xea2092701c016119      0t0  UDP [::1]:57351->[::1]:14567
beam.smp  50496 emqx   46u  IPv6 0xea2092701c017999      0t0  UDP [::1]:52353->[::1]:14567
beam.smp  50496 emqx   47u  IPv6 0xea2092701c017ca9      0t0  UDP [::1]:57640->[::1]:14567
beam.smp  50496 emqx   48u  IPv6 0xea2092701c014ba9      0t0  UDP [::1]:55992->[::1]:14567
beam.smp  51015 emqx   39u  IPv6 0xea2092701c017069      0t0  UDP [::1]:64686->[::1]:14567

Чтобы узнать больше о emqtt-bench, обратитесь к справке:

./emqtt_bench pub –help

./emqtt_bench conn –help

./emqtt_bench --help

Краткое содержание

Это первый взгляд на MQTT вместо QUIC. Как вы можете заметить, клиентские библиотеки и EMQX способны обеспечить тот же опыт, что и MQTT, на уровне API и уровне управления. Возможность воспользоваться всеми преимуществами функции QUIC, просто заменив транспортный уровень, очень удобна для разработчиков и способствовала популярности MQTT по сравнению с QUIC. Кроме того, поддержка NanoMQ для соединения MQTT через мост QUIC также обеспечивает еще одно гибкое решение.

Поскольку MQTT поверх QUIC широко используется в реальном мире, пользователи также могут использовать расширенные функции, такие как контроль перегрузки, плавный перенос соединений, сквозное шифрование и рукопожатие с малой задержкой. Оставайтесь с нами для получения более подробных объяснений методов и передовых методов, лежащих в основе этих функций.

Первоначально опубликовано на https://www.emqx.com.