I'm using camel-kafka version 2.14.3 . I used client acknowledge while reading from ibm MQ by creating the bean as follows
<bean id="ibmMQwithClientAck" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration">
<bean class="org.apache.camel.component.jms.JmsConfiguration">
<property name="acknowledgementModeName"
value="CLIENT_ACKNOWLEDGE" />
<property name="connectionFactory">
<bean class="com.ibm.mq.jms.MQConnectionFactory">
<property name="transportType" value="<transportType>" />
<property name="hostName" value="<hostName>" />
<property name="port" value="<port>" />
<property name="channel" value="<channel>" />
<property name="queueManager" value="<queueManager>" />
</bean>
</property>
</bean>
</property>
</bean>
I'm looking for client commit in camel-kafka. Can this be accomplished from consumer itself, or something needs to configured at the kafka cluster end?
I'm using camel-kafka version 2.14.3 .
Below is the kafka URI :
<from uri="kafka:{brokerlist}?topic={topic-name}&zookeeperHost={zookeeperHost}&zookeeperPort={zookeeperPort}&groupId={groupId-name}&consumerStreams=2" />
You can use manual commit via allowManualCommit=true, see the docs at: https://camel.apache.org/components/2.x/kafka-component.html
At the section: https://camel.apache.org/components/2.x/kafka-component.html#_using_manual_commit_with_kafka_consumer
Related
It is mentioned in the documentation of DefaultMessageListenerContainer class that it is not recommended to use CachingConnectionFactory with dynamic scaling. While searching, I have encountered following link:
Why DefaultMessageListenerContainer should not use CachingConnectionFactory?
Here found a comment from Gary Russell that
the problem is with caching consumers when using variable concurrency in the container; we can end up with a live consumer "stuck" in the cache".
We have used DefaultMessageListenerContainer and CachingConnectionFactory together so this is surely a problem from above link.
We are encountering problems with our application having following behaviour:
TCP ZeroWindow network congestion
TCP RESET from application server to MQ
DB connection grows during the issue while different transactions halt
Messages in certain queues gets built up
We have following code configuration :
In ibmmq-context.xml file:
<!-- WebSphere MQ Connection Factory -->
<bean id="appMqConnectionFactory" class="com.ibm.mq.jms.MQConnectionFactory">
<property name="hostName">
<value>${ibmmq.ip}</value>
</property>
<property name="port">
<value>${ibmmq.port}</value>
</property>
<property name="queueManager">
<value>${ibmmq.queuemanager}</value>
</property>
<property name="channel">
<value>${ibmmq.channel}</value>
</property>
<property name="clientReconnectOptions">
<util:constant static-field="com.ibm.msg.client.wmq.WMQConstants.WMQ_CLIENT_RECONNECT"/>
</property>
<property name="transportType" ref="appTransport"/>
</bean>
<!-- A cached connection -->
<bean id="appCachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="appMqConnectionFactory"/>
<property name="sessionCacheSize" value="${jms.session.cachesize}"/>
</bean>
<!-- Use native MQ classes. -->
<bean id="appTransport" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField">
<value>com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP</value>
</property>
</bean>
In jms-context file:
<bean id="bankListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="cachedConnectionFactory" />
<property name="destination" ref="transactionResponseDestination" />
<property name="messageListener" ref="thirdpartyService" />
<property name="autoStartup" value="false"/>
<property name="taskExecutor" ref="listenerExecutor"/>
<property name="concurrency" value="20-30"/>
</bean>
There are 6 such listeners like bankListener and each of the listeners has concurrency value, varies from 10-40
<bean id="listenerExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="maxPoolSize" value="140"/>
<property name="corePoolSize" value="100"/>
<property name="queueCapacity" value="30"/>
<property name="threadNamePrefix" value="jms-listener-task-"/>
<property name="threadGroupName" value="jms-listener-tasks"/>
</bean>
and jms-context.xml file uses ibmmq-context.xml file.
And to note, we have used IBM MQ 7.1, Spring 4.2.8, spring-integration-core as 4.3.1.RELEASE and JBoss EAP 6.4.10
We are planning to fix this by following way:
<bean id="bankListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="appMqConnectionFactory" />
<property name="destination" ref="transactionResponseDestination" />
<property name="messageListener" ref="thirdpartyService" />
<property name="autoStartup" value="false"/>
<property name="taskExecutor" ref="listenerExecutor"/>
<property name="concurrency" value="20-30"/>
</bean>
My request:
Please review the configuration and let me know is there anything else to be changed.
Could you please also explain our application behaviour(above 4 points - a to d) with our current configuration with CachingConnectionFactory and DefaultMessageListenerContainer
Thanks in advance for your help.
Try setting:
cachingConnectionFactory.setCacheConsumers(false);
Or in Spring it should be:
<bean id="appCachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
...
<property name="cacheConsumers" value="false"/>
...
</bean>
I'm really struggling to get my Spring JMS template to work and send messages to a queue. Here's what I've got attempted:
In my XML:
<bean name="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="mqQueueConnectionFactory" />
<property name="defaultDestination" ref="mqQueue" />
</bean>
<bean name="mqQueue" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="${MQ_QUEUE_MANAGER_NAME}" />
<constructor-arg value="${MQ_QUEUE_NAME}" />
</bean>
<bean name="mqQueueConnectionFactory" class="com.ibm.mq.jms.MQXAQueueConnectionFactory">
<property name="hostName" value="${MQ_HOST_NAME}" />
<property name="channel" value="${MQ_CHANNEL}" />
<property name="port" value="${MQ_PORT}" />
<property name="queueManager" value="${MQ_QUEUE_MANAGER_NAME}" />
<property name="transportType" ref="wmq_cl_binding" />
</bean>
So those are my beans for setting up the template/queue.
Now I setup a listener and jmsContainer:
<bean id="messageListener" class="CloseoutListener" />
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="mqQueueConnectionFactory" />
<property name="destination" ref="mqQueue" />
<property name="messageListener" ref="messageListener" />
</bean>
and my implementation of CloseoutListener is the same that is on the Spring JMS docs: Listener
In addition to this, I am trying to send a message in the same way that Spring sends a message in the docs: Sender
Full disclosure: First time using queues and any sort of JMS, as well as my second time using Spring so I'm aware if this is sloppy or just plain wrong. That's why I'm asking for assistance.
No message is appearing in the queue and in addition I'm getting this message in my logs:
INFO DefaultMessageListenerContainer.handleListenerSetupFailure :825 - JMS message listener invoker needs to establish shared Connection
I read on : http://www.javaworld.com/article/2074123/java-web-development/transaction-and-redelivery-in-jms.html?page=2
"Generally, acknowledging a particular message acknowledges all prior messages the session receives" ( in Client acknowledgement mode )
"Message redelivery is not automatic, but messages are redelivered under certain circumstances"
My questions :
how can I ensure there is a new session every time I recive a message (but reuse the connection)?
how to enforce the redelivery for un acknowledge message ?
Im using this configration :
<bean id="jmsConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory"
lazy-init="true">
<property name="queueManager" value="${queueManager}" />
<property name="hostName" value="${hostName}" />
<property name="transportType" value="${transportType}" />
<property name="port" value="${port}" />
<property name="channel" value="${channel}" />
<property name="SSLCipherSuite" value="${SSLCipherSuite}" />
</bean>
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="maxConnections" value="10"/>
<property name="maximumActive" value="100"/>
<property name="connectionFactory" ref="jmsConnectionFactory"/>
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="transacted" value="false"/>
</bean>
<bean id="mqNonJmsDestRes" class="calypsox.tk.util.NonJmsMQQueueDestinationResolver" />
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration" ref="jmsConfig" />
<property name="acknowledgementModeName" value="CLIENT_ACKNOWLEDGE" />
<property name="destinationResolver" ref="mqNonJmsDestRes" />
</bean>
and I use camel processor as endpoint bean as singleton
That article you referenced is from 2002. All of the MQ based systems have received a lot of work since then. On your AMQ PooledConnectionFactory there are settings to control how long your connections last before they are destroyed and what you should do if you encounter an error. I recommend reading into some of the newer documentation since there has been a lot of changes in the last 14 years. So some things have become much easier.
You can also check into the exceptionListener on "org.apache.camel.component.jms.JmsComponent" to configure how to manage exceptions and even write your own if the current options don't suit your needs.
I have a Batch Job Configured to read messages from JMS Destination and write to a XML file using Chuck Tasklet. The JMS reader is custom implemented which inturn invokes JMSTemplate's receive method. I am using webMethods Broker as JMS Broker. During Batch run, we observed that the Consumer session created while reading the messages from Broker Destination are not being destroyed up on completion of the batch. They are only destroyed after I shutdown the JVM. I have provided more details below,
JMS Spring XML Configuration :
<bean id="JMS.SourceQueue.JndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<map>
<entry key="java.naming.provider.url" value="wmjmsnaming://Broker #1#X.X.X.X:6849" />
<entry key="java.naming.factory.initial" value="com.webmethods.jms.naming.WmJmsNamingCtxFactory" />
<entry key="com.webmethods.jms.naming.clientgroup" value="IS-JMS" />
</map>
</property>
</bean>
<bean id="JMS.SourceQueue.JmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="JMS.SourceQueue.JndiTemplate" />
<property name="jndiName" value="SmartBatchConnectionFactory" />
<property name="lookupOnStartup" value="true" />
<property name="cache" value="false" />
<property name="proxyInterface" value="javax.jms.ConnectionFactory" />
</bean>
<bean id="JMS.SourceQueue.ConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="JMS.SourceQueue.JmsConnectionFactory" />
</bean>
<bean id="JMS.SourceQueue.DefaultDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="JMS.SourceQueue.JndiTemplate" />
<property name="jndiName" value="SourceQueue" />
</bean>
<bean id="JMS.SourceQueue.MessageTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JMS.SourceQueue.ConnectionFactory" />
<property name="receiveTimeout" value="10000" />
<property name="sessionTransacted" value="true" />
<property name="defaultDestination" ref="JMS.SourceQueue.DefaultDestination" />
</bean>
Any help on pointing out the actual issue would be great.
Call destroy() on the JMS.SourceQueue.ConnectionFactory at the end of the last step (or otherwise when the job is completed).
Using the caching connection factory is recommended to avoid creating connections/consumers for each message, but it needs to be told when to physically release the resources.
How can i turn on authentication using jmx on spring web app ?
Please take a look here for a solution that is almost working for me:
http://forum.springsource.org/showthread.php?t=73677
The only unresolved issue is how to make JMX client use the same connection to server when authenticating and when doing the secure operation.
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean">
<property name="objectName" value="connector:name=rmi" />
<property name="serviceUrl" value="service:jmx:rmi:///jndi/rmi://:9875/jmxrmi" />
<property name="environment">
<map>
<entry key="jmx.remote.x.password.file" value="C:\Java\jdk1.7.0_79\jre\lib\management\jmxremote.password" />
<entry key="jmx.remote.x.access.file" value="C:\Java\jdk1.7.0_79\jre\lib\management\jmxremote.access" />
</map>
</property>
</bean>
SpringConfig
<bean id="annotationTestMBean" class="com.greenline.appservice.web.bean.AnnotationTestMBean"/>
<!-- Spring JMX 配置 begin -->
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="port" value="9875" />
<property name="alwaysCreate" value="true" />
</bean>
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean">
<property name="objectName" value="connector:name=rmi" />
<property name="serviceUrl" value="service:jmx:rmi:///jndi/rmi://192.168.214.63:9875/myconnector" />
<!--jmxmp协议
<property name="objectName" value="connector:name=jmxmp" />
<property name="serviceUrl" value="service:jmx:jmxmp://192.168.214.63:9875" />
-->
<property name="environment">
<!-- the following is only valid when the sun jmx implementation is used -->
<map>
<entry key="jmx.remote.x.password.file" value="C:\Java\jdk1.7.0_79\jre\lib\management\jmxremote.password" />
<entry key="jmx.remote.x.access.file" value="C:\Java\jdk1.7.0_79\jre\lib\management\jmxremote.access" />
</map>
</property>
</bean>
<context:mbean-export registration="replaceExisting"/>
<!-- Spring JMX 配置 end-->
you can see access&password file
JDK_Path\jre\lib\management\jmxremote.password
JDK_Path\jre\lib\management\jmxremote.access
JMX and Spring Part1-3
http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-1.html
oracle-Remote Management Applications (jmx)
http://docs.oracle.com/cd/E19698-01/816-7609/6mdjrf861/index.html