Timer Apache Camel MQ连接池和计时器路由
我有一个web服务,它与Camel一起接收Soap调用并将消息写入队列。同一服务还有一个计时器路由,它检查队列并逐个处理消息。web服务在多个服务器上的Tomcat容器上运行,后端队列是Websphere MQ 我在Tomcat context.xml中有如下配置:Timer Apache Camel MQ连接池和计时器路由,timer,apache-camel,connection-pooling,Timer,Apache Camel,Connection Pooling,我有一个web服务,它与Camel一起接收Soap调用并将消息写入队列。同一服务还有一个计时器路由,它检查队列并逐个处理消息。web服务在多个服务器上的Tomcat容器上运行,后端队列是Websphere MQ 我在Tomcat context.xml中有如下配置: <Resource name="jms/MyQueueConnectionFactory" auth="Container" type="com.ibm.mq.jms.MQQueueConnectionFactory"
<Resource name="jms/MyQueueConnectionFactory" auth="Container"
type="com.ibm.mq.jms.MQQueueConnectionFactory"
factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
description="My Queue Connection Factory "
CHANNEL="CLIENT.MYCHANNEL" HOST="localhost.com" PORT="3663"
QMGR="MYCHANNEL" TRAN="1" UCP="Y" />
<Environment name="jms/QmgrUsername" value="appuser" type="java.lang.String" />
<Environment name="jms/QmgrPassword" value="password1" type="java.lang.String" />
生产者非常直截了当,它得到一个Soap调用,验证消息并执行一些操作,然后将其放入MQ。计时器使用者每5分钟轮询一次队列,并处理队列消息
import java.util.Calendar;
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.PollingConsumer;
import org.springframework.stereotype.Component;
import com.cambia.enroll.web.service.CheckHealthRequest;
import com.myapp.exception.InternalErrorException;
import com.myapp.elog.exception.QueueException;
@Component
public class QueueConsumer {
private static String inQueue = "myQueue:queue:QAW.MYAPP.IN";
public void processQueueOnTimer(String queueTimer, Exchange exchange) {
try {
synchronized (this) {
readFromQueue(exchange, inQueue);
}
} catch (Exception e) {
System.out.println("An unknown exception occured in processQueueOnTimer, throw Internal error", e);
}
}
private void readFromQueue(Exchange exchange, String queueName) throws QueueException, Exception {
String operationName = "";
CamelContext springCamelContext = exchange.getContext();
Endpoint endpoint = springCamelContext.getEndpoint(queueName);
PollingConsumer consumer = endpoint.createPollingConsumer();
Exchange queueMessage = exchange;
int count = 0;
try {
int timeout = 10000; // Default value if cannot read from property file
// Read all messages from the queue
while(true) {
queueMessage = consumer.receive(timeout);
if (null == queueMessage || null == queueMessage.getIn()) {
break;
}
//process each queue message
}
} catch (Exception e) {
throw new QueueException("Failure in readFromQueue for " + operationName + ": ", queueMessage, e);
}
}
}
很抱歉,我的问题如下:)
1) Tomcat和spring将如何管理producer组件的连接?它是否合并?我在队列连接工厂中使用UCP=“Y”标志,但这是适用于Tomcat池还是仅在MQ管理器端?我使用.to(inQueue)将消息放入队列。2) 我是否为计时器路由上的使用者使用池连接?我将获取由camel生成的默认Exchange主体,然后使用该主体获取CamelContext、Endpoint、PollingConsumer。对于计时器路由,我是否正确地执行了此操作,或者是否有其他方法获得池连接。
3) 如何监视JMS连接状态?有没有办法查看池中的连接数、新连接数和已释放的连接数等?
4) 在尝试访问同一后端队列的多个实例上使用使用者客户端或计时器路由是否存在任何问题?到目前为止,我还没有注意到日志上有任何异常活动 谢谢
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.LoggingLevel;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import com.myapp.camelconsumer.QueueConsumer;
import com.myapp.camelproducer.QueueProducer;
public class EventRouter extends RouteBuilder {
final private static String camelRouteURI = "cxf:/EventService?wsdlURL=classpath:wsdl/EventService.wsdl&serviceClass=EventService";
final private static String inQueue = "myQueue:queue:QAW.MYAPP.IN";
final private static String timerUrl = "timer://EventService?period=5m";
@Autowired
private QueueProducer producer;
@Autowired
private QueueConsumer consumer;
@Override
public void configure() throws Exception {
from(timerUrl)
.bean(consumer, "processQueueOnTimer('queueTimer')");
from(camelRouteURI).recipientList(simple("direct:${header.operationName}"));
from("direct:useEventService")
.bean(producer, "processQueueRoute('useEventService')")
.setExchangePattern(ExchangePattern.InOnly)
.to(inQueue)
.bean(producer, "setSuccessResponse('success')");
}
}
import java.util.Calendar;
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.PollingConsumer;
import org.springframework.stereotype.Component;
import com.cambia.enroll.web.service.CheckHealthRequest;
import com.myapp.exception.InternalErrorException;
import com.myapp.elog.exception.QueueException;
@Component
public class QueueConsumer {
private static String inQueue = "myQueue:queue:QAW.MYAPP.IN";
public void processQueueOnTimer(String queueTimer, Exchange exchange) {
try {
synchronized (this) {
readFromQueue(exchange, inQueue);
}
} catch (Exception e) {
System.out.println("An unknown exception occured in processQueueOnTimer, throw Internal error", e);
}
}
private void readFromQueue(Exchange exchange, String queueName) throws QueueException, Exception {
String operationName = "";
CamelContext springCamelContext = exchange.getContext();
Endpoint endpoint = springCamelContext.getEndpoint(queueName);
PollingConsumer consumer = endpoint.createPollingConsumer();
Exchange queueMessage = exchange;
int count = 0;
try {
int timeout = 10000; // Default value if cannot read from property file
// Read all messages from the queue
while(true) {
queueMessage = consumer.receive(timeout);
if (null == queueMessage || null == queueMessage.getIn()) {
break;
}
//process each queue message
}
} catch (Exception e) {
throw new QueueException("Failure in readFromQueue for " + operationName + ": ", queueMessage, e);
}
}
}