简体   繁体   English

为什么MQTT在QoS = 1的情况下减速太多?

[英]Why MQTT slows so much with QoS = 1?

I'm trying to write an application controlling a swarm of robots via WiFi and MQTT protocol. 我正在尝试编写一个通过WiFi和MQTT协议控制一大堆机器人的应用程序。 I have performed some tests to measure will it be fast enough for my application. 我已经进行了一些测试,以测量它是否足够快我的应用程序。 I would like to have a control loop (a message going from a PC to robot and back) that takes no more than 25-30ms average. 我想有一个控制循环(从PC到机器人和返回的消息)平均不超过25-30ms。

I have written an application using Paho Java client, that runs on two machines. 我使用Paho Java客户端编写了一个应用程序,它运行在两台机器上。 When one receives a message on topic1, it publishes to topic2. 当在topic1上收到消息时,它会发布到topic2。 Topic2 is subscribed by the second machine, that in turn publishes to topic1. Topic2由第二台机器订阅,而第二台机器又发布到topic1。

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

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

When all publishing and subscribing was made with QoS 0 a loop time was around 12ms average. 当所有发布和订阅都使用QoS 0时,循环时间平均约为12ms。 However I would like to use QoS 1 to guarantee that the commands sent to robots will always reach their destination. 但是,我想使用QoS 1来保证发送到机器人的命令将始终到达目的地。 When I tested the loop time, it averaged at around 250ms. 当我测试循环时间时,它平均在250ms左右。

What causes so much increase in time? 是什么导致这么多时间的增加? From my understanding, if there are no transmission errors, the exchanged packets number just doubles with QoS1 (there are PUBACKs sent from broker to clients for every message, see http://www.hivemq.com/mqtt-essentials-part-6-mqtt-quality-of-service-levels/ ). 根据我的理解,如果没有传输错误,交换的数据包数量只会增加一倍于QoS1(每个消息都有从代理发送到客户端的PUBACK,请参阅http://www.hivemq.com/mqtt-essentials-part-6 -mqtt-quality-of-level-levels / )。

Can I somehow reduce this time? 我可以以某种方式减少这个时间吗? I have tried Mosquitto and Apache Apollo brokers, both replicated the same results. 我尝试过Mosquitto和Apache Apollo经纪人,两者都复制了相同的结果。

Edit: 编辑:

I have changed a testing procedure a bit. 我稍微改变了测试程序。 Now, I have two instances of mqtt clients running on the same machine. 现在,我有两个mqtt客户端实例在同一台机器上运行。 One as a publisher, second as a subscriber. 一个是发布者,另一个是订阅者。 Publisher sends 1000 messages in 10ms intervals like this: Publisher以10ms的间隔发送1000条消息,如下所示:

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++;
}

While subscriber just waits for messages and measures time: 订阅者只需等待消息并测量时间:

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);
    }
}

Broker (mosquitto with default config), runs on a separate machine in the same local network. Broker(具有默认配置的mosquitto)在同一本地网络中的单独机器上运行。 The results that I have achieved are even more bizarre than before. 我取得的成果比以前更奇怪。 Now, it takes approximately 8-9ms for a message with QoS 1 to get to the subscriber. 现在,具有QoS 1的消息需要大约8-9ms才能到达订户。 With QoS 2 it's around 20ms. 使用QoS 2大约20ms。 However, with QoS 0, I get avg. 但是,使用QoS 0,我得到平均值。 times from 100ms to even 250ms! 时间从100ms到甚至250ms! I guess that the error is somewhere in my test method, but I can't see where. 我想错误是在我的测试方法中的某个地方,但我看不到哪里。

QoS 0 messages are not required to be persisted - they can be maintained entirely in memory. 不需要保留QoS 0消息 - 它们可以完全保留在内存中。

To be able to assure the QoS 1 (and QoS 2) delivery, the messages need to be persisted in some form. 为了能够确保QoS 1(和QoS 2)传递,消息需要以某种形式保持。 This adds additional processing time to the messages over the simple network transfer time. 这会在简单的网络传输时间内为消息增加额外的处理时间。

The implication of 2 totally different broker implementations showing the same results could be that it's the client side of the code that is taking the time to respond with the ack packet. 2个完全不同的代理实现显示相同结果的含义可能是代码的客户端花费时间来响应ack数据包。

Are you doing all the processing of an incoming method in the onMessage callback? 你是否在onMessage回调中对传入方法进行了所有处理? If so this work will be being done on the same thread as all the MQTT protocol handling which could delay a response. 如果是这样,这项工作将在与可能延迟响应的所有MQTT协议处理相同的线程上完成。 For high volume/high speed message processing the pattern normally used is to only use the onMessage call back to queue the incoming message for another thread to actually process. 对于高容量/高速消息处理,通常使用的模式是仅使用onMessage回调对传入消息进行排队,以便另一个线程实际处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM