Почему MQTT так сильно замедляется с QoS = 1?

Я пытаюсь написать приложение, управляющее роем роботов по протоколу WiFi и MQTT. Я провел несколько тестов, чтобы измерить, будет ли это достаточно быстро для моего приложения. Я хотел бы иметь контрольный цикл (сообщение, идущее от ПК к роботу и обратно), который занимает в среднем не более 25-30 мс.

Я написал приложение с использованием Java-клиента Paho, которое работает на двух машинах. Когда кто-то получает сообщение по теме1, он публикует в теме2. Тема 2 подписана на второй машине, которая, в свою очередь, публикуется в теме 1.

    topic1            topic1
M1---------> broker ---------> M2

    topic2            topic2
M1 <-------- broker <--------- M2

Когда все публикации и подписки выполнялись с QoS 0, время цикла составляло в среднем около 12 мс. Однако я хотел бы использовать QoS 1, чтобы гарантировать, что команды, отправляемые роботам, всегда будут достигать пункта назначения. Когда я тестировал время цикла, оно составляло в среднем 250 мс.

Что вызывает так много увеличения во времени? Насколько я понимаю, если нет ошибок передачи, количество обмениваемых пакетов просто удваивается с QoS1 (есть PUBACK, отправленные брокером клиентам для каждого сообщения, см. http://www.hivemq.com/mqtt-essentials-part-6-mqtt-quality-of-service-levels/).

Можно ли как-то сократить это время? Я пробовал брокеров Mosquitto и Apache Apollo, оба повторяли одинаковые результаты.

Редактировать:

Я немного изменил процедуру тестирования. Теперь у меня есть два экземпляра клиентов mqtt, работающих на одной машине. Один как издатель, второй как подписчик. Издатель отправляет 1000 сообщений с интервалами в 10 мс, например:

Client publisher = new Client(url, clientId+"pub", cleanSession, quietMode, userName, password);
Client subscriber = new Client(url, clientId+"sub", cleanSession, quietMode, userName, password);
subscriber.subscribe(pubTopic, qos);

while (counter < 1000) {
    Thread.sleep(10,0);
    String time = new Timestamp(System.currentTimeMillis()).toString();
    publisher.publish(pubTopic, qos, time.getBytes());

    counter++;
}

Пока абонент просто ждет сообщений и измеряет время:

public void messageArrived(String topic, MqttMessage message) throws MqttException {
// Called when a message arrives from the server that matches any
    // subscription made by the client

    Timestamp tRec = new Timestamp(System.currentTimeMillis());
    String timeSent = new String(message.getPayload());
    Timestamp tSent = Timestamp.valueOf(timeSent);
    long diff = tRec.getTime() - tSent.getTime();
    sum += diff;

    counter++;

    if (counter == 1000) {
        double avg = sum / 1000.0;
        System.out.println("avg time: " + avg);
    }
}

Брокер (mosquitto с конфигурацией по умолчанию), работает на отдельной машине в той же локальной сети. Результаты, которых я достиг, еще более странные, чем раньше. Теперь для получения сообщения с QoS 1 для подписчика требуется приблизительно 8-9 мс. С QoS 2 это около 20 мс. Однако с QoS 0 я получаю среднее значение. время от 100 до 250 мс! Я предполагаю, что ошибка где-то в моем методе тестирования, но я не могу видеть, где.

2 ответа

Сообщения QoS 0 не обязательно должны сохраняться - они могут храниться полностью в памяти.

Чтобы обеспечить доставку QoS 1 (и QoS 2), сообщения должны быть сохранены в некоторой форме. Это добавляет дополнительное время обработки к сообщениям по сравнению с простым временем передачи по сети.

Смысл двух совершенно разных реализаций брокера, показывающих одинаковые результаты, может заключаться в том, что клиентская часть кода тратит время на ответ с помощью пакета ack.

Вы делаете всю обработку входящего метода в обратном вызове onMessage? Если это так, эта работа будет выполняться в том же потоке, что и вся обработка протокола MQTT, которая может задержать ответ. Для обработки большого объема / высокой скорости сообщения обычно используется шаблон, который использует только обратный вызов onMessage, чтобы поставить в очередь входящее сообщение, чтобы другой поток действительно обработал его.

Другие вопросы по тегам