我是jms的新手。目标是在异步侦听器的onMessage方法中从队列中并发处理消息,方法是将侦听器实例连接到多个使用者,每个使用者使用自己的会话并在单独的线程中运行,这样消息就会传递给不同的使用者并发处理。
1)是否可以通过创建多个消费者来从单个队列同时处理消息? 2)我想出了下面的代码,但是想知道下面的代码是否适合我想要完成的内容。
public class QueueConsumer implements Runnable, MessageListener {
public static void main(String[] args) {
QueueConsumer consumer1 = new QueueConsumer();
QueueConsumer consumer2 = new QueueConsumer();
try {
consumer1.init("oms", "US.Q.CHECKOUT-ORDER.1.0.JSON");
consumer2.init("oms","US.Q.CHECKOUT-ORDER.1.0.JSON");
} catch (JMSException ex) {
ex.printStackTrace();
System.exit(-1);
}
Thread newThread1 = new Thread(consumer1);
Thread newThread2 = new Thread(consumer1);
newThread1.start();
newThread2.start();
}
private static String connectionFactoryName = null;
private static String queueName = null;
private static ConnectionFactory qcf = null;
private static Connection queueConnection = null;
private Session ses = null;
private Destination queue = null;
private MessageConsumer msgConsumer = null;
public static final Logger logger = LoggerFactory
.getLogger(QueueConsumer.class);
public QueueConsumer() {
super();
}
public void onMessage(Message msg) {
if (msg instanceof TextMessage) {
try {
//process message
} catch (JMSException ex) {
ex.printStackTrace();
}
}
}
public void run() {
try {
queueConnection.start();
} catch (JMSException e) {
e.printStackTrace();
System.exit(-1);
}
while (!Thread.currentThread().isInterrupted()) {
synchronized (this) {
try {
wait();
} catch (InterruptedException ex) {
break;
}
}
}
}
public void init(String factoryName, String queue2) throws JMSException {
try {
qcf = new JMSConnectionFactory(factoryName);
queueConnection = qcf.createConnection();
ses = queueConnection.createSession(false,
Session.CLIENT_ACKNOWLEDGE);
queue = ses.createQueue(queue2);
logger.info("Subscribing to destination: " + queue2);
msgConsumer = ses.createConsumer(queue);
msgConsumer.setMessageListener(this);
System.out.println("Listening on queue " + queue2);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
private static void setConnectionFactoryName(String name) {
connectionFactoryName = name;
}
private static String getQueueName() {
return queueName;
}
private static void setQueueName(String name) {
queueName = name;
}
}
答案 0 :(得分:2)
我只是简单地看一下,我注意到你把错误的消费者传递给你的第二个帖子:
Thread newThread2 = new Thread(consumer1); // has to pass consumer2
除此之外,一些变量如ConnectionFactory
是静态的并且多次初始化/覆盖。您只需要一个可以创建多个会话和/或消费者的连接。
答案 1 :(得分:0)
与您提供的代码示例相关,Oracle不建议在已部署的应用程序上创建低级线程。 Weblogic示例: Using Threads in WebLogic Server
答案 2 :(得分:0)
您可以在并发的消费者属性中添加并发使用者属性,而不是在其中放置邮件容器bean的applicationcontext.xml中。
<bean id="jmsMailContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers">
<value>100</value>
</property>
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="mailDestination"/>
<property name="messageListener" ref="jmsMailConsumer"/>