单个队列:具有多个使用者的并发消息处理

时间:2013-06-13 03:37:47

标签: jms

我是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;
}

}

3 个答案:

答案 0 :(得分:2)

  1. 是绝对的
  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"/>