I'm trying to send a lot of JMS messages to an IBM MQ broker with the awesome Apache Camel library.
When I'm sending 1000 small (less than 100 bytes) messages sending rate is really slow (1 msg/second) with Apache Camel. When I'm doing the same send without Camel sending rate is 50 msg/second. I don't understand why because the two examples are using an MQConnectionFactory with the same parameters.
Here is the code with Apache Camel library:
MQConnectionFactory factory = new MQConnectionFactory();
factory.setHostName("tcp://myhost");
factory.setPort(1414);
factory.setChannel("mychannel");
factory.setQueueManager("myqueuemanager");
factory.setAppName("myAppName");
factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
factory.setStringProperty(WMQConstants.USERID, "myuser");
factory.setStringProperty(WMQConstants.PASSWORD, "mypassword");
// Set SSL properties for MTLS
factory.setSSLCipherSuite(this.localConf.getString("ssl.ciphers"));
System.setProperty("javax.net.ssl.keyStore", "somekeystore.js");
System.setProperty("javax.net.ssl.keyStorePassword", "mykeystorepassword");
System.setProperty("javax.net.ssl.trustStore", "somekeystore.js");
System.setProperty("javax.net.ssl.trustStorePassword", "mykeystorepassword.js");
var component = JmsComponent.jmsComponentClientAcknowledge(factory);
//Creating a new camel context
context = new DefaultCamelContext();
context.addComponent( "ibmmq", component);
context.addRoutes(new RouteBuilder() {
@Override
public void configure() {
from("timer:myTimer?period=1&delay=0").setBody(constant("message content inferior to 100 bytes"))
//Envois vers IBM
.to("ibmmq:queue:myQueueName");
}
});
context.start();
I'm lost in the resolution of this issue:
- it can't be a broker limitation because my standard test without Camel is 50x faster
- it can't be the factory because it's the same in two tests
Is there a misconfiguration in my Camel code?
Edit
Here is my simple java code without camel running 50x faster:
// Variables
JMSContext context = null;
Destination destination = null;
JMSProducer producer = null;
JMSConsumer consumer = null;
try {
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set the properties
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, host);
cf.setIntProperty(WMQConstants.WMQ_PORT, port);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channel);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, qManagerName);
cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "JmsPutGet (JMS)");
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
cf.setStringProperty(WMQConstants.USERID, user);
cf.setStringProperty(WMQConstants.PASSWORD, password);
context = cf.createContext();
destination = context.createQueue("queue:///" + qname);
for(int i=0;i<1000;i++){
long uniqueNumber = System.currentTimeMillis() % 1000;
TextMessage message = context.createTextMessage("Your lucky number today is " + uniqueNumber);
message.setStringProperty("myCustomHeader","header1");
producer = context.createProducer();
producer.send(destination, message);
System.out.println("Sent message:\n" + message);
}
context.close();
nb: if i create a custom component on camel with my simple java code in it, the speed is 50msg/sc too so i think the problem coming from the JmsComponent.jmsComponentClientAcknowledge() but i dont know why and i dont want to rewrite the all component and it's safety mechanisms (it's so risky)
sendmethod on the JMSMessageProducer? If so, that code is doing considerably less work than Camel although I'm not sure that would account for the entire 50x difference. Have you tried profiling the Camel code to see where it's spending its time?producer.setDeliveryMode(DeliveryMode.PERSISTENT);to your simple Java example, you can check if it is related to persistent messages vs. non-persistent messages.