ActiveMQ configured with Camel+Spring idle time out setting not working - spring

I am trying to configure a stable connection which doesn't timeout with the embedded ActiveMQ broker. I am using Camel+ActiveMQ+Spring to configure on the server side. In my broker config I have the below config, I have tried setting connectionTimeOut , wireFormat.maxInactivityDuration=0 on the transport connectors but didn't work, I am using StompClient to connect ws://localhost:61614/stomp?useInactivityMonitor=false on the client side. The connection gets established but it times out after 300000ms which seems to be the default idle time but can't turn it off, please help at which level this should be configured to ensure the connections don't get dropped :
<broker id="broker" brokerName="myBroker" useShutdownHook="false" useJmx="true" dataDirectory="activemq-data"
xmlns="http://activemq.apache.org/schema/core">
<transportConnectors>
<!-- vm transport for intra-jvm communication-->
<transportConnector name="vm" uri="vm://myBroker?transport.useInactivityMonitor=false"/>
<!-- tcp for external communication -->
<transportConnector name="tcp" uri="tcp://localhost:61616?transport.useInactivityMonitor=false"/>
<transportConnector name="ws" uri="ws://localhost:61614??transport.useInactivityMonitor=false"/>
<transportConnector name="stomp" uri="stomp://localhost:61613?transport.useInactivityMonitor=false"/>
</transportConnectors>
</broker>
<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="vm://myBroker?create=false&waitForStart=5000" />
</bean>
<bean id="pooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="maxConnections" value="12" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="idleTimeout" value="120000" />
</bean>
<bean id="jmsConfig"
class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="concurrentConsumers" value="12"/>
<property name="idleConsumerLimit" value="120000"/>
</bean>
<bean id="activemq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="configuration" ref="jmsConfig"/>
</bean>
Getting this in the log while disconnecting :
WebSocketConnectionRFC6455 DEBUG ClosedOut WebSocketServletConnectionRFC6455 p=WebSocketParserRFC6455#3565d22 state=OPCODE buffer=null g=WebSocketGeneratorRFC6455#309b59a6 closed=false buffer=-1 1000 Idle for 300074ms > 300000ms

It turned out to be the Jetty under the ActiveMQ causing this issue. It has a default idle time out of 300000ms, setting the transport connector as below increased the time out to the set value, setting it to '0' doesn't disable the inactivity monitor as it's suggested for "wireFormat.maxInactivityDuration=0", and using the "wireFormat.maxInactivityDuration=0" alone doesn't work either :
<transportConnectors>
<!-- vm transport for intra-jvm communication-->
<transportConnector name="vm" uri="vm://myBroker"/>
<transportConnector name="ws" uri="ws://localhost:61614?websocket.maxIdleTime=7200000"/>
</transportConnectors>
on the client side, I have the matching URL just in case : "ws://localhost:61614?maxIdleTime=7200000".
Couldn't find this in the regular ActiveMQ documentation or anywhere else. It would be nice to see the docs updated for this scenario.

Related

Configure Http connection pooling in Apache CXF

I'm using Apache camel 2.16.0 and CXF 3.1.2
How can i configure connection pooling (in cxf.xml) for all the http calls so that it can reuse the existing http connection instead of create a new connection every time ?
I see too may TIME_WAIT, CLOSE_WAIT and FIN_WAIT2 for each request, How can i close idle connections ?
<bean id="http" class="org.apache.camel.component.http.HttpComponent">
<property name="camelContext" ref="camel_context" />
<property name="httpConnectionManager" ref="myHttpConnectionManager" />
</bean>
<bean id="myHttpConnectionManager"
class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">
<property name="params" ref="myHttpConnectionManagerParams" />
</bean>
<bean id="myHttpConnectionManagerParams"
class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">
<property name="connectionTimeout" value="20000" />
<property name="soTimeout" value="20000" />
<property name="defaultMaxConnectionsPerHost" value="5" />
<property name="maxTotalConnections" value="10" />
</bean>
seems like maxTotalConnections isn't working !
maxTotalConnections is 10 but when i do a load test i can see more than 230 ESTABLISHED connections.. not only this
all the properties like connectionTimeout, soTimeout, defaultMaxConnectionsPerHost are all ignored !
any help is appreciated..

DefaultMessageListenerContainer recoveryInterval with specific retry count

We are using Spring Integration in our project and we have a requirement where If IBM MQ goes down then we will have to auto connect to IBM MQ when it is up. We have done this implementation using recoveryInterval option of org.springframework.jms.listener.DefaultMessageListenerContainer class. We have given recovery interval as 6 seconds so every 6 seconds system try to recover the MQ connection but now we have a requirement where we will have to do the autorecover twice only and after that if still MQ is down then stop the inbound adapter.
Is there any way in Spring Integration to mention the auto recovery retry count so that system will try to recover only for that retry count?
Below is my existing configuration.
<bean id="inQ" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="${mq.inbound.queue}" />
</bean>
<int:channel id="inbound" />
<int-jms:message-driven-channel-adapter
id="jmsIn" channel="inbound" container="messageListenerContainer"
acknowledge="transacted" auto-startup="false">
</int-jms:message-driven-channel-adapter>
<int:service-activator id="mainService"
input-channel="inbound" ref="messageListener" method="onMessage">
<int:request-handler-advice-chain>
<ref bean="retryWithBackoffAdviceSession" />
</int:request-handler-advice-chain>
</int:service-activator>
<bean id="messageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="mqConnectionFactory" />
<property name="destination" ref="inQ" />
<property name="sessionTransacted" value="true" />
<property name="maxConcurrentConsumers" value="${maxConcurrentConsumers}" />
<property name="concurrentConsumers" value="${concurrentConsumers}" />
<property name="receiveTimeout" value="${receiveTimeout}" />
<property name="recoveryInterval" value="60000" />
<property name="autoStartup" value="${autoStartup}" />
</bean>
Thanks
Sach
As an alternative to the recoveryInterval, you can now specify a Backoff instead (see the docs).
It doesn't provide a mechanism to stop the container but an appropriate backoff can effectively do what you want.
You would then need to programmatically stop/start to kick it off again.

Use ActiveMQ in Travis CI

My build in Travis CI failed after add configuration on Active MQ.
The log of Travis CI shows:
Caused by: javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: java.net.ConnectException: Connection refused
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36)
at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:360)
at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:305)
at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:245)
at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:365)
at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:305)
at org.springframework.jms.connection.SingleConnectionFactory.getConnection(SingleConnectionFactory.java:283)
at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:224)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:180)
at org.springframework.jms.listener.AbstractJmsListeningContainer.createSharedConnection(AbstractJmsListeningContainer.java:413)
at org.springframework.jms.listener.AbstractJmsListeningContainer.establishSharedConnection(AbstractJmsListeningContainer.java:381)
at org.springframework.jms.listener.AbstractJmsListeningContainer.doStart(AbstractJmsListeningContainer.java:285)
at org.springframework.jms.listener.SimpleMessageListenerContainer.doStart(SimpleMessageListenerContainer.java:209)
at org.springframework.jms.listener.AbstractJmsListeningContainer.start(AbstractJmsListeningContainer.java:270)
... 44 more
I'm using Spring MVC, here's the configuration for testing:
<beans "Some DTDs here">
<!-- Base Components -->
<context:annotation-config />
<context:component-scan base-package="com.trunkshell.voj" />
<!-- Some other configuration for JDBC and other service -->
<!-- Message Service -->
<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg index="0" value="tcp://localhost:61616"/>
</bean>
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="amqConnectionFactory" />
</bean>
<bean id="defaultDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="vojMessageQueue"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="defaultDestination" ref="defaultDestination" />
</bean>
<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destinationName" value="vojMessageQueue" />
<property name="messageListener" ref="messageReceiver" />
</bean>
<bean id="messageSender" class="com.trunkshell.voj.util.MessageSender"></bean>
<bean id="messageReceiver" class="com.trunkshell.voj.util.MessageReceiver"></bean>
</beans>
I also noticed that Travis CI only support RabbitMQ and ZeroMQ.
Here's the reference: link
So what should I do to fix the error in Travis CI?
Or how to skip this problem in Travis CI.
I don't see that you actually start an ActiveMQ broker at port 61616. Either, do that, or preferably use the VM transport during the integration tests. I.e. change tcp://localhost:61616 to vm://localhost?broker.persistent=false
Of course, you have to be able to change that ActiveMQ URL when you deploy to a production environment. Maybe you can use spring property placeholders?

JBoss AS 7.1 Remoting JMX Not working

I have an MBean (JMX) which is exposed through RMI in a JBoss AS 7.1 Server but I can't access it. I already follow all of the tutorials revolving around but it just cant work.
This is how I exposed my MBean
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
<bean id="mBeanExporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry
key="test:name=foo"
value-ref="foo" />
</map>
</property>
<property name="server" ref="mbeanServer" />
</bean>
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="port" value="1399" />
</bean>
<bean id="serverConnector"
class="org.springframework.jmx.support.ConnectorServerFactoryBean">
<property name="objectName" value="connector:name=rmi" />
<property name="serviceUrl"
value="service:jmx:rmi://192.168.1.108/jndi/rmi://192.168.1.108:1399/myconnector" />
<property name="server">
<ref local="mbeanServer" />
</property>
</bean>
How can I remotely access this in Jconsole ?
I've already tried these:
service:jmx:remoting-jmx://192.168.1.108:9999
service:jmx:rmi:///jndi/rmi://192.168.1.108:1090/jmxrmi
service:jmx:rmi:///jndi/rmi://192.168.1.108:1090/myconnector
And many more but none of those work.
What am I doing wrong or what should I do ?
On JBoss 7 /EAP6 is can't use rmi for remote jmx calls, JBoss uses remoting-jmx protocol for jmx.
You can see a full example in: Using Spring to call jmx bean on JBoss7 / EAP 6

Camel jms to external activeMQ with request-reply gives javax.jms.InvalidDestinationException: Cannot publish to a deleted Destination:

We have third party applications that make restful calls to camel cxfrs endpoint which is then routed to an external activeMQ. There are applications consuming these JMS messages and provide XML responses. This is all done synchronously using camel InOut exchangePattern. The architecture is very straight forward and simple. We were using activeMQ 5.5.0-fuse, camel-jms 2.8.x and activemq-pool 5.6.
Using this configuration, we see this exception at random times:
javax.jms.InvalidDestinationException: Cannot publish to a deleted Destination: temp- queue://ID:testserver-37266-1366126830205-0:0:1
at org.apache.activemq.ActiveMQSession.send(ActiveMQSession.java:1696)
at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:231)
at org.apache.activemq.pool.PooledProducer.send(PooledProducer.java:74)
at org.apache.activemq.pool.PooledProducer.send(PooledProducer.java:55)
When this happens the server just stalls and none of our services respond until we restart activeMQ, tomcat and all other services.
camel config:
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<bean id="routeBuilder" class="gov.nasa.arc.tmi.route.TMIServiceRoute"/>
<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<property name="marshallerProperties" ref="propertiesMap"/>
</bean>
<util:map id="propertiesMap">
<entry key="jaxb.formatted.output">
<value type="java.lang.Boolean">true</value>
</entry>
</util:map>
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="routeBuilder"/>
</camelContext>
<bean id="activemq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="tcp://localhost:61616"/>
Camel Router class:
//reroute
from("cxfrs:/rr?resourceClasses=x.y.z.route.RerouteResource")
.setExchangePattern(ExchangePattern.InOut)
.process(new RerouteProcessor())
.to("activemq:queue:x.y.z.tmi.request");
Here is the spring configuration of the application that listens on queue:x.y.z.tmi.request consumes JMS messages:
<context:annotation-config/>
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL">
<value>tcp://localhost:61616? wireFormat.maxInactivityDurationInitalDelay=30000</value>
</property>
</bean>
<bean id="pooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="maxConnections" value="8" />
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="gov.nasa.arc.tmi.request"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="defaultDestination" ref="destination" />
</bean>
<jms:listener-container connection-factory="pooledConnectionFactory" concurrency="10">
<jms:listener destination="gov.nasa.arc.tmi.request" ref="tmiQueryListener" />
After googling, I came across these bugs:
https://issues.apache.org/jira/browse/CAMEL-6229
https://issues.apache.org/jira/browse/AMQ-3457
Based on these, we upgraded to camel 2.10.4, activeMq 5.7 and activemq-pool 5.7. Even so, the problem remains.
I am really stuck and don't know how to resolve this issue. Can some one kindly point out what could be wrong?
Thanks.
I wonder if its because the processing the JMS message on the other side takes too long, and then the inactive monitor of ActiveMQ deletes the temp destination as its been inactive for > 30 seconds. http://activemq.apache.org/activemq-inactivitymonitor.html
Maybe try to set the timeout to a higher value, or disable it.
Another option is to use fixed queues for reply queues instead of temp queues.

Resources