FAQ
Hi,

we found that Camel together with the JMS component over Websphere MQ is
quite slow, it takes up to a second for Camel to forward a message.
There is an old bug which might explain this behaviour:
New JMS connection being created for every message
https://issues.apache.org/jira/browse/CAMEL-604

I did a trace of MQ within Camel, and there were indeed a lot of MQOPEN
calls, so I guess the problem is still there.

Can anybody confirm this? Is the bug still there? Is there a work-around?
Any chance of this bug getting fixed?

Thanks,
Juergen

--
View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5637735.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Search Discussions

  • Christian Schneider at Apr 13, 2012 at 9:59 am
    The behaviour is caused by spring jms and is normal. The spring jms code
    opens and closes the connection for every call. This is the expected
    behaviour in JEE environments.
    To improve the performance you need connection pooling.

    Spring provides the
    http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/jms/connection/CachingConnectionFactory.html
    for that.
    You can wrap your original connection factory with it.

    Alternatively you can check if MQ provides a pooling connection factory.

    Christian


    Am 13.04.2012 11:11, schrieb weberj:
    Hi,

    we found that Camel together with the JMS component over Websphere MQ is
    quite slow, it takes up to a second for Camel to forward a message.
    There is an old bug which might explain this behaviour:
    New JMS connection being created for every message
    https://issues.apache.org/jira/browse/CAMEL-604

    I did a trace of MQ within Camel, and there were indeed a lot of MQOPEN
    calls, so I guess the problem is still there.

    Can anybody confirm this? Is the bug still there? Is there a work-around?
    Any chance of this bug getting fixed?

    Thanks,
    Juergen

    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5637735.html
    Sent from the Camel - Users mailing list archive at Nabble.com.

    --
    Christian Schneider
    http://www.liquid-reality.de

    Open Source Architect
    Talend Application Integration Division http://www.talend.com
  • Weberj at Apr 25, 2012 at 2:20 pm
    Hi,

    OK, as you suggested I configured the
    org.springframework.jms.connection.CachingConnectionFactory. It deploys but
    on initializing there is

    com.ibm.msg.client.jms.DetailedIllegalStateException: MQJCA1031: The method
    can only be called in the application client container. The application was
    not running in the application client container when this method was called.
    Ensure that the application runs in the application client container, or
    modify the application to avoid this method call.

    This seems to be similar to
    https://community.jboss.org/thread/156545

    An MQ Trace showed that the caller was
    org.springframework.jms.connection.SingleConnectionFactory.prepareConnection(SingleConnectionFactory.java:364)

    So I hacked
    prepareConnection(Connection) und commented out
    con.setExceptionListener(listenerToUse);

    But now there is
    MQJCA1018: Only one session per connection is allowed. The application
    attempted to create more than one JMS session on the same JMS connection.
    This exception occurs only if the application is running in a managed
    environment. Modify the application so that it creates only one JMS session
    on a JMS connection.

    at
    com.ibm.mq.connector.outbound.ConnectionWrapper.createSession(ConnectionWrapper.java:113)
    at
    org.springframework.jms.connection.SingleConnectionFactory.createSession(SingleConnectionFactory.java:406)

    Has anybody an idea what that means?

    I guess I should try the MQ connection pool instead of Spring's.

    Thanks,
    Juergen


    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5664989.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Christian Schneider at Apr 25, 2012 at 3:42 pm
    Never saw that before how does your init code look like? Or do you
    do it in spring?

    Where do you run your application?

    Christian

    Am 25.04.2012 16:19, schrieb weberj:
    Hi,

    OK, as you suggested I configured the
    org.springframework.jms.connection.CachingConnectionFactory. It deploys but
    on initializing there is

    com.ibm.msg.client.jms.DetailedIllegalStateException: MQJCA1031: The method
    can only be called in the application client container. The application was
    not running in the application client container when this method was called.
    Ensure that the application runs in the application client container, or
    modify the application to avoid this method call.

    This seems to be similar to
    https://community.jboss.org/thread/156545

    An MQ Trace showed that the caller was
    org.springframework.jms.connection.SingleConnectionFactory.prepareConnection(SingleConnectionFactory.java:364)

    So I hacked
    prepareConnection(Connection) und commented out
    con.setExceptionListener(listenerToUse);

    But now there is
    MQJCA1018: Only one session per connection is allowed. The application
    attempted to create more than one JMS session on the same JMS connection.
    This exception occurs only if the application is running in a managed
    environment. Modify the application so that it creates only one JMS session
    on a JMS connection.

    at
    com.ibm.mq.connector.outbound.ConnectionWrapper.createSession(ConnectionWrapper.java:113)
    at
    org.springframework.jms.connection.SingleConnectionFactory.createSession(SingleConnectionFactory.java:406)

    Has anybody an idea what that means?

    I guess I should try the MQ connection pool instead of Spring's.

    Thanks,
    Juergen


    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5664989.html
    Sent from the Camel - Users mailing list archive at Nabble.com.

    --
    Christian Schneider
    http://www.liquid-reality.de

    Open Source Architect
    Talend Application Integration Division http://www.talend.com
  • Weberj at Apr 26, 2012 at 8:48 am
    Yes, the pool is defined in Spring XML. Camel should run in JBoss 4, MQ is in
    the resource adapter (therefore the "application client container"
    complaint).
    Guess I'll have to remote debug the code..

    The connection and route definitions cannot be totally wrong, as one or two
    messages are delivered until the error comes up.

    Juergen


    <bean id="jmswsmq" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="mqConnectionFactoryWrapper" />
    <property name="acknowledgementModeName" value="AUTO_ACKNOWLEDGE" />
    </bean>

    <bean id="mqConnectionFactoryWrapper"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="mqJmsConnectionFactoryJNDI"
    />
    </bean>

    <jee:jndi-lookup id="mqJmsConnectionFactoryJNDI" jndi-name="java:wmqcf" />

    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5667039.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Christian Schneider at Apr 26, 2012 at 9:03 am
    In a container like jboss it should not be necessary to use the
    CachingConnectionFactory. Instead you should configure the resource
    adapter to support pooling.

    Then you can simply lookup the ConnectionFactory on jndi and use it as
    it is.

    The CachingConnectionFactory is typically used when you are not running
    in a container.

    Christian

    Am 26.04.2012 10:47, schrieb weberj:
    Yes, the pool is defined in Spring XML. Camel should run in JBoss 4, MQ is in
    the resource adapter (therefore the "application client container"
    complaint).
    Guess I'll have to remote debug the code..

    The connection and route definitions cannot be totally wrong, as one or two
    messages are delivered until the error comes up.

    Juergen


    <bean id="jmswsmq" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="mqConnectionFactoryWrapper" />
    <property name="acknowledgementModeName" value="AUTO_ACKNOWLEDGE" />
    </bean>

    <bean id="mqConnectionFactoryWrapper"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="mqJmsConnectionFactoryJNDI"
    />
    </bean>

    <jee:jndi-lookup id="mqJmsConnectionFactoryJNDI" jndi-name="java:wmqcf" />

    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5667039.html
    Sent from the Camel - Users mailing list archive at Nabble.com.

    --
    Christian Schneider
    http://www.liquid-reality.de

    Open Source Architect
    Talend Application Integration Division http://www.talend.com
  • Weberj at Apr 26, 2012 at 9:41 am
    This was my original configuration that pooling was in the resource adapter
    (the MQ RA has a default of 10 maxConnections).
    But when Camel closes the connection this somehow seems to close the RA's
    underlying connection, too.

    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5667139.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Christian Schneider at Apr 26, 2012 at 10:56 am
    This is then probably an issue with the resource adapter. As far a I
    understood a Java EE application is expected to close the connection
    after each method call and the
    pool should then handle that this still is performant.

    Christian

    Am 26.04.2012 11:40, schrieb weberj:
    This was my original configuration that pooling was in the resource adapter
    (the MQ RA has a default of 10 maxConnections).
    But when Camel closes the connection this somehow seems to close the RA's
    underlying connection, too.

    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5667139.html
    Sent from the Camel - Users mailing list archive at Nabble.com.

    --

    Christian Schneider
    http://www.liquid-reality.de

    Open Source Architect
    Talend Application Integration Division http://www.talend.com
  • Weberj at Apr 30, 2012 at 1:52 pm
    No, the resource adapter is fine. I wrote a simple MDB that uses the RA and
    just echoes back a message to the reply Q. In the onMessage() call I create
    and close the connection. This MDB can handle 20 messages/s, whereas Camel
    handles only one.


    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5676000.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Christian Schneider at Aug 1, 2012 at 8:38 pm
    Just to recap what we found today. The reason for the bad performance
    seems to be that camel polls for replies in the producer with a default
    of 1000ms. Setting receiveTimeout=10 on the producer seems to speed up
    the route a lot.

    After we found that your colleague also found that this is actually
    documented in the camel-jms documentation :-)
    http://camel.apache.org/jms.html
    I added the relevant section below.

    I am not really sure why the receiveTimeout really controls the polling
    but it works. In any case the option name looks a bit misleading. I
    guess pollingIntervall would
    be more acurate.

    Christian

    -----


    Request-reply over JMS and using a shared fixed reply queue

    If you use a fixed reply queue when doing Request Reply
    <http://camel.apache.org/request-reply.html> over JMS as shown in the
    example below, then pay attention.

    from(xxx)
    .inOut().to("activemq:queue:foo?replyTo=bar")
    .to(yyy)

    In this example the fixed reply queue named "bar" is used. By default
    Camel assumes the queue is shared when using fixed reply queues, and
    therefore it uses a JMSSelector to only pickup the expected reply
    messages (eg based on the JMSCorrelationID). See next section for
    exclusive fixed reply queues. That means its not as fast as temporary
    queues. You can speedup how often Camel will pull for reply messages
    using the receiveTimeout option. By default its 1000 millis. So to make
    it faster you can set it to 250 millis to pull 4 times per second as shown:

    from(xxx)
    .inOut().to("activemq:queue:foo?replyTo=bar&receiveTimeout=250")
    .to(yyy)

    Notice this will cause the Camel to send pull requests to the message
    broker more frequent, and thus require more network traffic.
    It is generally recommended to use temporary queues if possible.



    Am 30.04.2012 15:52, schrieb weberj:
    No, the resource adapter is fine. I wrote a simple MDB that uses the RA and
    just echoes back a message to the reply Q. In the onMessage() call I create
    and close the connection. This MDB can handle 20 messages/s, whereas Camel
    handles only one.


    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5676000.html
    Sent from the Camel - Users mailing list archive at Nabble.com.

    --

    Christian Schneider
    http://www.liquid-reality.de

    Open Source Architect
    Talend Application Integration Division http://www.talend.com
  • Claus Ibsen at Aug 13, 2012 at 7:25 am

    On Wed, Aug 1, 2012 at 10:33 PM, Christian Schneider wrote:
    Just to recap what we found today. The reason for the bad performance seems
    to be that camel polls for replies in the producer with a default
    of 1000ms. Setting receiveTimeout=10 on the producer seems to speed up the
    route a lot.

    After we found that your colleague also found that this is actually
    documented in the camel-jms documentation :-)
    http://camel.apache.org/jms.html
    I added the relevant section below.

    I am not really sure why the receiveTimeout really controls the polling but
    it works. In any case the option name looks a bit misleading. I guess
    pollingIntervall would
    be more acurate.
    Its the name of the option the spring guys gave it.

    Use a temporary or exclusive queue for the reply message is faster, as
    JMS message selectors i not needed, and then the receiveTimeout doen't
    matter.

    Christian

    -----


    Request-reply over JMS and using a shared fixed reply queue

    If you use a fixed reply queue when doing Request Reply
    <http://camel.apache.org/request-reply.html> over JMS as shown in the
    example below, then pay attention.

    from(xxx)
    .inOut().to("activemq:queue:foo?replyTo=bar")
    .to(yyy)

    In this example the fixed reply queue named "bar" is used. By default Camel
    assumes the queue is shared when using fixed reply queues, and therefore it
    uses a JMSSelector to only pickup the expected reply messages (eg based on
    the JMSCorrelationID). See next section for exclusive fixed reply queues.
    That means its not as fast as temporary queues. You can speedup how often
    Camel will pull for reply messages using the receiveTimeout option. By
    default its 1000 millis. So to make it faster you can set it to 250 millis
    to pull 4 times per second as shown:

    from(xxx)
    .inOut().to("activemq:queue:foo?replyTo=bar&receiveTimeout=250")
    .to(yyy)

    Notice this will cause the Camel to send pull requests to the message broker
    more frequent, and thus require more network traffic.
    It is generally recommended to use temporary queues if possible.



    Am 30.04.2012 15:52, schrieb weberj:
    No, the resource adapter is fine. I wrote a simple MDB that uses the RA
    and
    just echoes back a message to the reply Q. In the onMessage() call I
    create
    and close the connection. This MDB can handle 20 messages/s, whereas Camel
    handles only one.


    --
    View this message in context:
    http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5676000.html
    Sent from the Camel - Users mailing list archive at Nabble.com.


    --
    Christian Schneider
    http://www.liquid-reality.de

    Open Source Architect
    Talend Application Integration Division http://www.talend.com


    --
    Claus Ibsen
    -----------------
    FuseSource
    Email: cibsen@fusesource.com
    Web: http://fusesource.com
    Twitter: davsclaus, fusenews
    Blog: http://davsclaus.com
    Author of Camel in Action: http://www.manning.com/ibsen
  • David Karlsen at Apr 25, 2012 at 5:23 pm
    I would recommend using WMQ's internal pooling.
    Just set connectionPooling to true on the connectionfactory.

    2012/4/25 weberj <juergen@jwi.de>:
    Hi,

    OK, as you suggested I configured the
    org.springframework.jms.connection.CachingConnectionFactory. It deploys but
    on initializing there is

    com.ibm.msg.client.jms.DetailedIllegalStateException: MQJCA1031: The method
    can only be called in the application client container. The application was
    not running in the application client container when this method was called.
    Ensure that the application runs in the application client container, or
    modify the application to avoid this method call.

    This seems to be similar to
    https://community.jboss.org/thread/156545

    An MQ Trace showed that the caller was
    org.springframework.jms.connection.SingleConnectionFactory.prepareConnection(SingleConnectionFactory.java:364)

    So I hacked
    prepareConnection(Connection) und commented out
    con.setExceptionListener(listenerToUse);

    But now there is
    MQJCA1018: Only one session per connection is allowed. The application
    attempted to create more than one JMS session on the same JMS connection.
    This exception occurs only if the application is running in a managed
    environment. Modify the application so that it creates only one JMS session
    on a JMS connection.

    at
    com.ibm.mq.connector.outbound.ConnectionWrapper.createSession(ConnectionWrapper.java:113)
    at
    org.springframework.jms.connection.SingleConnectionFactory.createSession(SingleConnectionFactory.java:406)

    Has anybody an idea what that means?

    I guess I should try the MQ connection pool instead of Spring's.

    Thanks,
    Juergen


    --
    View this message in context: http://camel.465427.n5.nabble.com/New-JMS-connection-being-created-for-every-message-tp5637735p5664989.html
    Sent from the Camel - Users mailing list archive at Nabble.com.


    --
    --
    David J. M. Karlsen - http://www.linkedin.com/in/davidkarlsen

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupusers @
categoriescamel
postedApr 13, '12 at 9:11a
activeAug 13, '12 at 7:25a
posts12
users4
websitecamel.apache.org

People

Translate

site design / logo © 2022 Grokbase