Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JMS—从一个使用者到多个使用者_Java_Jms_Message Queue_Messaging - Fatal编程技术网

Java JMS—从一个使用者到多个使用者

Java JMS—从一个使用者到多个使用者,java,jms,message-queue,messaging,Java,Jms,Message Queue,Messaging,我有一个JMS客户机,它正在生成消息并通过JMS队列发送给其唯一的使用者 我想要的是不止一个消费者得到这些信息。我想到的第一件事是将队列转换为一个主题,这样当前和新的消费者都可以订阅并获得相同的消息 这显然涉及到修改当前客户端代码,包括生产者和消费者两方面 我还想看看其他选项,比如创建第二个队列,这样我就不必修改现有的使用者。我相信这种方法有很多优点,比如(如果我错了,请纠正我的错误)在两个不同队列而不是一个队列之间平衡负载,这可能会对性能产生积极影响 我想就您可能看到的这些选项和优缺点获得建议

我有一个JMS客户机,它正在生成消息并通过JMS队列发送给其唯一的使用者

我想要的是不止一个消费者得到这些信息。我想到的第一件事是将队列转换为一个主题,这样当前和新的消费者都可以订阅并获得相同的消息

这显然涉及到修改当前客户端代码,包括生产者和消费者两方面

我还想看看其他选项,比如创建第二个队列,这样我就不必修改现有的使用者。我相信这种方法有很多优点,比如(如果我错了,请纠正我的错误)在两个不同队列而不是一个队列之间平衡负载,这可能会对性能产生积极影响


我想就您可能看到的这些选项和优缺点获得建议。非常感谢您的反馈。

您可能不需要修改代码;这取决于你是怎么写的

例如,如果您的代码使用
MessageProducer
而不是
QueueSender
发送消息,那么它将适用于主题和队列。类似地,如果使用
MessageConsumer
而不是
QueueReceiver


本质上,在JMS应用程序中,使用非特定接口与JMS系统交互是一种很好的做法,例如
MessageProducer
MessageConsumer
Destination
,等等。如果是这样的话,“仅仅”是一个配置问题。

如您所述,您有几个选项

如果将其转换为主题以获得相同的效果,则需要使消费者成为持久的消费者。队列提供的一件事是,如果您的消费者不在,则持久性。这将取决于您使用的MQ系统

如果您想继续使用队列,您将为每个使用者创建一个队列,并创建一个将侦听原始队列的调度程序

Producer -> Queue_Original <- Dispatcher -> Queue_Consumer_1 <- Consumer_1
                                         -> Queue_Consumer_2 <- Consumer_2
                                         -> Queue_Consumer_3 <- Consumer_3

这是一个很好的回答。我使用的是JBoss的MOM实现,它是HornetQ。@Anonimo上次检查JBoss时,它绝对遵守JMS规范。这在过去给我造成了一些混乱,因为我动态创建了JMS规范没有考虑的主题。另一种类似ActiveMQ的方法允许您动态创建主题,并且只需要在JBoss中更改一行代码即可实现相同的功能。谢谢Andrew。请详细说明使用多个队列的想法好吗?根据您的解释,生产者代码没有更改,但不确定此调度程序位于何处,以及它在技术术语中的表示方式。@是的,我将很快发布它。这将是一个不错的选择。不幸的是,我们使用的是像QueueSender这样的特定接口。如果我们进行重构,我肯定会记住这一点。
Producer -> Queue_Original <- Dispatcher -> Queue_Consumer_1 <- Consumer_1
                                         -> Queue_Consumer_2 <- Consumer_2
                                         -> Queue_Consumer_3 <- Consumer_3
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package stackoverflow_4615895;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;

public class Dispatcher {

    private static long QUEUE_WAIT_TIME = 1000;
    private boolean mStop = false;
    private QueueConnectionFactory mFactory;
    private String mSourceQueueName;
    private String[] mConsumerQueueNames;

    /**
     * Create a dispatcher
     * @param factory
     *      The QueueConnectionFactory in which new connections, session, and consumers
     *      will be created. This is needed to ensure the connection is associated
     *      with the correct thread.
     * @param source
     *
     * @param consumerQueues
     */
    public Dispatcher(
        QueueConnectionFactory factory, 
        String sourceQueue, 
        String[] consumerQueues) {

        mFactory = factory;
        mSourceQueueName = sourceQueue;
        mConsumerQueueNames = consumerQueues;
    }

    public void start() {
        Thread thread = new Thread(new Runnable() {

            public void run() {
                Dispatcher.this.run();
            }
        });
        thread.setName("Queue Dispatcher");
        thread.start();
    }

    public void stop() {
        mStop = true;
    }

    private void run() {

        QueueConnection connection = null;
        MessageProducer producer = null;
        MessageConsumer consumer = null;
        QueueSession session = null;
        try {
            // Setup connection and queues for receiving the messages
            connection = mFactory.createQueueConnection();
            session = connection.createQueueSession(false, Session.DUPS_OK_ACKNOWLEDGE);
            Queue sourceQueue = session.createQueue(mSourceQueueName);
            consumer = session.createConsumer(sourceQueue);

            // Create a null producer allowing us to send messages
            // to any queue.
            producer = session.createProducer(null);

            // Create the destination queues based on the consumer names we
            // were given.
            Queue[] destinationQueues = new Queue[mConsumerQueueNames.length];
            for (int index = 0; index < mConsumerQueueNames.length; ++index) {
                destinationQueues[index] = session.createQueue(mConsumerQueueNames[index]);
            }

            connection.start();

            while (!mStop) {

                // Only wait QUEUE_WAIT_TIME in order to give
                // the dispatcher a chance to see if it should
                // quit
                Message m = consumer.receive(QUEUE_WAIT_TIME);
                if (m == null) {
                    continue;
                }

                // Take the message we received and put
                // it in each of the consumers destination
                // queues for them to process
                for (Queue q : destinationQueues) {
                    producer.send(q, m);
                }
            }

        } catch (JMSException ex) {
            // Do wonderful things here 
        } finally {
            if (producer != null) {
                try {
                    producer.close();
                } catch (JMSException ex) {
                }
            }
            if (consumer != null) {
                try {
                    consumer.close();
                } catch (JMSException ex) {
                }
            }
            if (session != null) {
                try {
                    session.close();
                } catch (JMSException ex) {
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException ex) {
                }
            }
        }
    }
}
    QueueConnectionFactory factory = ...;

    Dispatcher dispatcher =
            new Dispatcher(
            factory,
            "Queue_Original",
            new String[]{
                "Consumer_Queue_1",
                "Consumer_Queue_2",
                "Consumer_Queue_3"});
    dispatcher.start();