0

I am using simple MQTT client for publish and subscribe using Paho client java. I have limited resources of around 256MB or less of RAM (Linux machine with reduced capabilities). My QOS level is 0. My connection to mqtt broker is successful. I am able to send messages to broker successfully for an hour. My message rate is <= 1msg/s. After an hour my application just hangs. I read few posts on StackOverflow and other places and have setKeepAliveInterval as 120s and setTimeToWait as 1s(I have varied it from 2 min to 1s). I have tried async client, synchronous client with and without waitToComplete but it's reproducible in all cases. I have used both MemoryPersistence and File persistence - again reproducible in both cases. I have also tried topic.publish and client.publish - reproducible in both cases. Below is my code snippet:

@Override
  public void connect() {
    SSLContext sslContext = setSSLContext();

    connOpt = new MqttConnectOptions();
    connOpt.setSocketFactory(sslContext.getSocketFactory());
    connOpt.setCleanSession(true);
    connOpt.setUserName(userName);
    connOpt.setPassword(password);

    connOpt.setKeepAliveInterval(MQTT_KEEP_ALIVE_TIMEOUT_SECS);
    // Connect to Broker
    int retry = 1;
    while (retry <= MQTT_CONNECT_RETRIES) {
      try {
        client = new MqttClient("ssl://" + mqtt.getMqttBrokerIp(), someId, memPersistence);
        client.setCallback(callback);
        client.connect(connOpt);
        client.setTimeToWait(1000);
        logger.info("msg='Connection to mqtt broker successful'");
        return;
      } catch (MqttException e) {
        logger.warn(
            "err='Connection to mqtt broker failed', retryNumber={}, errMessage={}, errStack={}",
            retry, e.getMessage(), e.getStackTrace());
      }
      retry++;
    }
    logger.error("err='Connection to mqtt broker failed'");
  }

  @Override
  public void publish(String topicPublish, String message) {
    MqttMessage mqttMsg = new MqttMessage(message.getBytes());
    mqttMsg.setQos(QOS);
    mqttMsg.setRetained(false);
    try {
      client.publish(topicPublish, mqttMsg);
    } catch (MqttPersistenceException e) {
      logger.error("errMessage={}, errStack={}", e.getMessage(), e.getStackTrace());    
    } catch (MqttException e) {
      logger.error("errMessage={}, errStack={}", e.getMessage(), e.getStackTrace());    
    }
    /*
    MqttMessage mqttMsg = new MqttMessage(message.getBytes());
    MqttTopic topic = client.getTopic(topicPublish);
    mqttMsg.setQos(QOS);
    mqttMsg.setRetained(false);
    try {
      //memPersistence.clear();
      MqttDeliveryToken token = topic.publish(mqttMsg);
      token.waitForCompletion();
    } catch (MqttPersistenceException e) {
      logger.error("errMessage={}, errStack={}", e.getMessage(), e.getStackTrace());    
    } catch (MqttException e) {
      logger.error("errMessage={}, errStack={}", e.getMessage(), e.getStackTrace());    
    }
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      logger.debug(" exception ");   
    }
    */
  }

  @Override
  public void subscribe(String topicSubscribe) {
    try {
      client.subscribe(topicSubscribe, QOS);
    } catch (MqttException e) {
      logger.error("errMessage={}, errStack={}", e.getMessage(), e.getStackTrace());
    }
  } 

My code runs for 1 hour or so and then always hangs before coming to deliveryComplete(). I have logs there to check which never get printed. My code hangs on following logs:

org.eclipse.paho.client.mqttv3.internal.Token notifyComplete FINE: 2384: >key=2061 response=null excep=null

I am using

maven { url 'https://repo.eclipse.org/content/repositories/paho-releases/' } in repository and compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2' in my dependency in my build.gradle. I also tried

maven {
url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
} 

in my repository. It did not help. Could anyone please suggest what IK may be doing wrong. I have gone through a lot of examples and post and after that I am posting here.

DTCool
  • 33
  • 6
  • Did you search on their github's issue list? Search `hang` and you might wanna change a MQTT client... – John Zeng May 10 '17 at 02:58
  • @JohnZeng , I did. But they just have 2 issues related to hang. One is while disconnecting and the other is for messageArrive. A few others were related to QOS 1,2. I am on QOS 0 and really don't care about reliability at this point of time. – DTCool May 10 '17 at 05:50
  • 1.0.2 was released two years ago(2015) and there are 7 closed issues about `hang` and they all closed in 2016. Do you realize what's wrong here now? – John Zeng May 10 '17 at 09:15
  • @JohnZeng, I tried with `compile group: 'org.eclipse.paho', name: 'org.eclipse.paho.client.mqttv3' , version: '1.1.1'` but it still crashes (within 10 minutes at 1 msg/s rate). I increased my resources to 600 cpu and 350MB of RAM during the test. I ran the same application with unlimited compute and it's running for past 12 hours. I have a feeling resource is an issue. Is there a way I can control the MemoryPersistence or FilePersistence size? Because I am just running mqtt publish as an application right now with everything else disabled. – DTCool May 10 '17 at 18:23
  • 1
    If you have limited resource, I recommend you use c or go, some languages doesn't need vm, instead of java... I don't know how your application crashes, but if it doesn't crash with unlimited resource, you may wanna do some tunning on the jvm, that may help. JVM eat lost of memory and your kernel may kill it when it use too much memory, use `dmesg` to see if it's killed by kernel. – John Zeng May 11 '17 at 03:07

0 Answers0