Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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 ActiveMQ如果任务在生产者之后到达,则某些消费者不会接收任务_Java_Activemq_Producer Consumer - Fatal编程技术网

Java ActiveMQ如果任务在生产者之后到达,则某些消费者不会接收任务

Java ActiveMQ如果任务在生产者之后到达,则某些消费者不会接收任务,java,activemq,producer-consumer,Java,Activemq,Producer Consumer,我刚开始使用ActiveMQ,我似乎有一个奇怪的问题。(以下来源) 有两种情况 使用者连接到代理,等待队列上的任务。制作人稍后到达,放下任务列表,不同的消费者正确地接受并执行这些任务。这工作得很好,我也模拟了它 Producer首先连接,删除任务列表。此时未连接任何使用者。现在让我们假设3个消费者-C1、C2和C3连接到代理(按顺序),我看到只有C1拾取并执行生产者丢弃的任务。C2和C3保持怠速。为什么会发生这种情况 关于第二个场景,我还注意到了另外一件事——如果生产者继续在队列中丢弃任务,C2

我刚开始使用ActiveMQ,我似乎有一个奇怪的问题。(以下来源)

有两种情况

  • 使用者连接到代理,等待队列上的任务。制作人稍后到达,放下任务列表,不同的消费者正确地接受并执行这些任务。这工作得很好,我也模拟了它

  • Producer首先连接,删除任务列表。此时未连接任何使用者。现在让我们假设3个消费者-C1、C2和C3连接到代理(按顺序),我看到只有C1拾取并执行生产者丢弃的任务。C2和C3保持怠速。为什么会发生这种情况

  • 关于第二个场景,我还注意到了另外一件事——如果生产者继续在队列中丢弃任务,C2和C3会拾取任务,但如果生产者之前已经丢弃了任务(如前所述),则C2和C3不会做任何事情

    生产商代码

    package com.activemq.apps;
    
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageConsumer;
    import javax.jms.MessageListener;
    import javax.jms.MessageProducer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    
    import org.apache.activemq.ActiveMQConnectionFactory;
    
    import com.commons.helpers.Maths;
    
    public class Publisher implements MessageListener {
    
        private static String _URL;
        private static String _TOPIC_PUBLISH;
        private static String _TOPIC_CONSUME;
    
        public Publisher (String URL, String TOPIC) {
    
            _URL = URL;
            _TOPIC_PUBLISH = TOPIC + "_REQUESTS";
            _TOPIC_CONSUME = TOPIC + "_RESPONSES";
    
        }
    
        public void initialize() {
    
            try
            {
    
                ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(_URL);
                Connection connection = connectionFactory.createConnection();
                connection.start();
    
                Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
                Destination destinationProducer = session.createQueue(_TOPIC_PUBLISH);
                Destination destinationConsumers = session.createQueue(_TOPIC_CONSUME);
    
                MessageProducer producer = session.createProducer(destinationProducer);
                MessageConsumer consumer = session.createConsumer(destinationConsumers);
    
                consumer.setMessageListener(this);
    
                int count = 0;
    
                System.out.println("Sending requests");
    
                while (true)
                {
                    int randomSleepTime = Maths.rand(1000, 5000);
    
                    String messageToSend = count + "_" + randomSleepTime;
    
                    TextMessage message = session.createTextMessage(messageToSend);
    
                    producer.send(message);
    
                    System.out.println("Job #" + count + " | " + (randomSleepTime/1000) + "s");
    
                    if (count++%10 == 0)
                        Thread.sleep(10000);
    
                }
            }
    
            catch (JMSException ex)
            {
                ex.printStackTrace();
            }
    
            catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public void onMessage(Message message) {
    
            if (message instanceof TextMessage)
            {
                TextMessage msg = (TextMessage) message;
    
                try {
    
                    String response = msg.getText();
                    String[] responseSplit = response.split("_");
    
                    String clientId = responseSplit[1];
                    String count = responseSplit[0];
    
                    System.out.println("Got response from " + clientId + " Job #" + count);
                } 
    
                catch (JMSException e) {
                    e.printStackTrace();
                }
            }
    
        }
    
    }
    
    package com.activemq.apps;
    
    import java.util.UUID;
    
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageConsumer;
    import javax.jms.MessageListener;
    import javax.jms.MessageProducer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    
    import org.apache.activemq.ActiveMQConnectionFactory;
    
    public class Consumer implements MessageListener {
    
        private static String _URL;
        private static String _TOPIC_PUBLISH;
        private static String _TOPIC_CONSUME;
        private static String _CLIENTID;
    
        private MessageProducer producer;
        private Session session;
    
        public Consumer (String URL, String TOPIC) {
    
            _URL = URL;
            _TOPIC_PUBLISH = TOPIC + "_RESPONSES";
            _TOPIC_CONSUME = TOPIC + "_REQUESTS";
    
        }
    
        public void initialize() {
    
            try
            {
    
                _CLIENTID = UUID.randomUUID().toString();
    
                ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(_URL);
                Connection connection = connectionFactory.createConnection();
                connection.start();
    
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
                Destination destinationProducer = session.createQueue(_TOPIC_PUBLISH);
                Destination destinationConsumers = session.createQueue(_TOPIC_CONSUME);
    
                producer = session.createProducer(destinationProducer);
                MessageConsumer consumer = session.createConsumer(destinationConsumers);
    
                consumer.setMessageListener(this);
    
                System.out.println("Client: " + _CLIENTID + "\nWaiting to pick up tasks");
            }
    
            catch (JMSException ex)
            {
                ex.printStackTrace();
            }
    
        }
    
        @Override
        public void onMessage(Message message) {
    
            if (message instanceof TextMessage)
            {
                TextMessage msg = (TextMessage) message;
    
                try 
                {
    
                    String[] messageSplits = msg.getText().split("_");
    
                    String count = messageSplits[0];
                    String timeString = messageSplits[1];
    
                    int sleepFor = Integer.parseInt(timeString);
    
                    System.out.println("Job #" + count + " | Sleeping for " + (sleepFor/1000) + "s");
    
                    Thread.sleep(sleepFor);
    
                    TextMessage sendToProducer = session.createTextMessage(count + "_" + _CLIENTID);
    
                    producer.send(sendToProducer);
                } 
    
                catch (JMSException e) {
                    e.printStackTrace();
                } 
    
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
        }
    
    }
    
    消费者代码

    package com.activemq.apps;
    
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageConsumer;
    import javax.jms.MessageListener;
    import javax.jms.MessageProducer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    
    import org.apache.activemq.ActiveMQConnectionFactory;
    
    import com.commons.helpers.Maths;
    
    public class Publisher implements MessageListener {
    
        private static String _URL;
        private static String _TOPIC_PUBLISH;
        private static String _TOPIC_CONSUME;
    
        public Publisher (String URL, String TOPIC) {
    
            _URL = URL;
            _TOPIC_PUBLISH = TOPIC + "_REQUESTS";
            _TOPIC_CONSUME = TOPIC + "_RESPONSES";
    
        }
    
        public void initialize() {
    
            try
            {
    
                ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(_URL);
                Connection connection = connectionFactory.createConnection();
                connection.start();
    
                Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
                Destination destinationProducer = session.createQueue(_TOPIC_PUBLISH);
                Destination destinationConsumers = session.createQueue(_TOPIC_CONSUME);
    
                MessageProducer producer = session.createProducer(destinationProducer);
                MessageConsumer consumer = session.createConsumer(destinationConsumers);
    
                consumer.setMessageListener(this);
    
                int count = 0;
    
                System.out.println("Sending requests");
    
                while (true)
                {
                    int randomSleepTime = Maths.rand(1000, 5000);
    
                    String messageToSend = count + "_" + randomSleepTime;
    
                    TextMessage message = session.createTextMessage(messageToSend);
    
                    producer.send(message);
    
                    System.out.println("Job #" + count + " | " + (randomSleepTime/1000) + "s");
    
                    if (count++%10 == 0)
                        Thread.sleep(10000);
    
                }
            }
    
            catch (JMSException ex)
            {
                ex.printStackTrace();
            }
    
            catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public void onMessage(Message message) {
    
            if (message instanceof TextMessage)
            {
                TextMessage msg = (TextMessage) message;
    
                try {
    
                    String response = msg.getText();
                    String[] responseSplit = response.split("_");
    
                    String clientId = responseSplit[1];
                    String count = responseSplit[0];
    
                    System.out.println("Got response from " + clientId + " Job #" + count);
                } 
    
                catch (JMSException e) {
                    e.printStackTrace();
                }
            }
    
        }
    
    }
    
    package com.activemq.apps;
    
    import java.util.UUID;
    
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageConsumer;
    import javax.jms.MessageListener;
    import javax.jms.MessageProducer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    
    import org.apache.activemq.ActiveMQConnectionFactory;
    
    public class Consumer implements MessageListener {
    
        private static String _URL;
        private static String _TOPIC_PUBLISH;
        private static String _TOPIC_CONSUME;
        private static String _CLIENTID;
    
        private MessageProducer producer;
        private Session session;
    
        public Consumer (String URL, String TOPIC) {
    
            _URL = URL;
            _TOPIC_PUBLISH = TOPIC + "_RESPONSES";
            _TOPIC_CONSUME = TOPIC + "_REQUESTS";
    
        }
    
        public void initialize() {
    
            try
            {
    
                _CLIENTID = UUID.randomUUID().toString();
    
                ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(_URL);
                Connection connection = connectionFactory.createConnection();
                connection.start();
    
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
                Destination destinationProducer = session.createQueue(_TOPIC_PUBLISH);
                Destination destinationConsumers = session.createQueue(_TOPIC_CONSUME);
    
                producer = session.createProducer(destinationProducer);
                MessageConsumer consumer = session.createConsumer(destinationConsumers);
    
                consumer.setMessageListener(this);
    
                System.out.println("Client: " + _CLIENTID + "\nWaiting to pick up tasks");
            }
    
            catch (JMSException ex)
            {
                ex.printStackTrace();
            }
    
        }
    
        @Override
        public void onMessage(Message message) {
    
            if (message instanceof TextMessage)
            {
                TextMessage msg = (TextMessage) message;
    
                try 
                {
    
                    String[] messageSplits = msg.getText().split("_");
    
                    String count = messageSplits[0];
                    String timeString = messageSplits[1];
    
                    int sleepFor = Integer.parseInt(timeString);
    
                    System.out.println("Job #" + count + " | Sleeping for " + (sleepFor/1000) + "s");
    
                    Thread.sleep(sleepFor);
    
                    TextMessage sendToProducer = session.createTextMessage(count + "_" + _CLIENTID);
    
                    producer.send(sendToProducer);
                } 
    
                catch (JMSException e) {
                    e.printStackTrace();
                } 
    
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
        }
    
    }
    

    我不认为这里有什么奇怪的地方。队列表示P2P模式,该模式应该只有一个消费者。在我们的案例中,我们有3个消费者,这是不被禁止的,但不能保证消费者接收消息的任何特定顺序。

    您已经提到过

    现在让我们假设3个消费者-C1、C2和C3连接到代理 (按该顺序)

    由于C1首先连接,所以它在连接之后立即开始获取队列上的所有消息。这是意料之中的。所以我看不出有什么问题。C2、C3不空闲,但C1在C2和C3空闲之前已获得消息


    我不知道制作人发了多少信息。我假设消息的数量更少。要了解您的期望,请尝试从制作人处发送数千条或数百万条消息,然后启动消费者。大量消息是主观的,取决于内存、网络和其他资源。您可能会看到您的期望。

    我认为您应该为您的消费者检查预取策略参数。默认情况下,预取策略的默认值为1000。这意味着第一个消费者最多可以获取1000条消息,而其他消费者则无法获取任何其他消息。如果您正在尝试负载平衡,您的消息通过消费者考虑将此参数修改为0或1。 我明白了。那么基本实现本身是错误的?那么我应该用主题来代替吗?另外,你能推荐一些我可以更清楚地理解这些概念的地方吗?提前谢谢,我没说错。主题将以不同的方式工作,所有3个消费者将收到相同的消息。若你们想组织并行处理队列似乎不错。有一种方法可以替代Message Listener。您可以在并行线程中运行使用者,每个使用者都会使用MessageConsumer.read(超时)以一个周期进行读取。请尝试包说明,它位于页面底部。好的,我也会尝试。但我似乎无法理解,为什么只有第一个人(C1)负责处理任务,而其他人则无所事事,制作人添加了更多的任务,C2和C3开始行动。如果他们能把任务排出来,他们不应该在第一组任务上也排出来吗?我理解。我正在从制作人向队列发送10条消息。你说“C1在C2和C3之前就掌握了信息”是什么意思?我在管理屏幕上看到,消息是一个接一个地排出来的。我将尝试立即发送大量邮件,然后返回给您。返回并将邮件数量增加到2000条。现在C2和C3也在接受任务。就像你说的,这一定是对消息数量的限制。