简体   繁体   English

ActiveMQ生产者多个队列一个会话

[英]ActiveMQ Producer Multiple Queues One Session

How is it possible to enqueue messages to different queues using a persistent connection / session in ActiveMQ? 如何在ActiveMQ中使用持久连接/会话将消息排入不同的队列?

What I have done: 我做了什么:

public class ActiveMQProducer {

    private static final Logger LOGGER = Logger.getLogger(ActiveMQProducer.class);
    private Connection connection;
    private MessageProducer producer;
    private Session session;
    String activeMQConnection;

    public ActiveMQProducer() throws ConfigurationException, JMSException {
        activeMQConnection = ActiveMQPropertyManagerFactory.getInstance().getString("active.mq.url");
    }

    public void setupActiveMQ(String queueName) throws JMSException {

        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(activeMQConnection);
        factory.setRejectedTaskHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        connection = factory.createConnection();
        connection.start();

        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue(queueName);
        producer = session.createProducer(queue);

    }

    public void getConnection(String queueName) throws JMSException {

        if (connection == null || session == null) {
            Object object = new Object();
            synchronized (object) {
                setupActiveMQ(queueName);
            }
        }
    }

    public <T extends Serializable> T sendToActiveMQ(String queueName, T t) throws JMSException {
        getConnection(queueName);
        ObjectMessage message = session.createObjectMessage(t);
        producer.send(message);
        return null;
    }

    public void sendMessageToActiveMQ(String queueName, String message) throws JMSException {
        getConnection(queueName);
        TextMessage toSend = session.createTextMessage(message);
        producer.send(toSend);
    }
}

I have realized by using this and sending a message to a different queue eventually ActiveMQ runs out of connections because I never close the connection or session: 我已经意识到,通过使用此方法并将消息发送到其他队列,最终ActiveMQ会用尽连接,因为我从未关闭连接或会话:

org.apache.activemq.transport.tcp.ExceededMaximumConnectionsException: Exceeded the maximum number of allowed client connections.

What would be the proper way to handle this? 处理此问题的正确方法是什么? I have about 5 queues I have to send different messages to, should I open a new connection, enqueue and close the connection, is there anyway to keep the session / connections persistent? 我大约有5个队列,我必须向其发送不同的消息,我应该打开一个新的连接,入队并关闭该连接,还是要保持会话/连接的持久性?

Thanks. 谢谢。

here some solutions : 这里有一些解决方案:

1 Producer per destination : 每个目的地1个生产者:

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ConfigurationException;
import org.apache.log4j.Logger;

public class ActiveMQProducer {

    private static final Logger LOGGER = Logger.getLogger(ActiveMQProducer.class);
    private Connection connection;
    private Session session;
    String activeMQConnection;
    Map<String, MessageProducer> producers = Collections.synchronizedMap(new HashMap<String, MessageProducer>());
    Thread shutdownHook = new Thread(new Runnable() {
        @Override
        public void run() {
            close();
        }
    });

    public ActiveMQProducer() throws ConfigurationException, JMSException {
        activeMQConnection = ActiveMQPropertyManagerFactory.getInstance().getString("active.mq.url");
        setupActiveMQ();
        Runtime.getRuntime().addShutdownHook(shutdownHook);
    }

    public void setupActiveMQ() throws JMSException {
        close();
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(activeMQConnection);
        factory.setRejectedTaskHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        connection = factory.createConnection();
        connection.start();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    }

    @Override
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }

    public void close() {
        if (connection != null) {
            try {
                connection.close();
            } catch (Exception e) {
            }
            connection = null;
        }
    }

    public void getConnection() throws JMSException {
        if (connection == null || session == null) {
            setupActiveMQ();
        }
    }

    public MessageProducer getProducer(String queueName) throws JMSException {
        getConnection();
        MessageProducer producer = producers.get(queueName);
        if (producer == null) {
            Queue queue = session.createQueue(queueName);
            producer = session.createProducer(queue);
            producers.put(queueName, producer);
        }
        return producer;
    }

    public <T extends Serializable> T sendToActiveMQ(String queueName, T t) throws JMSException {
        MessageProducer producer = getProducer(queueName);
        ObjectMessage message = session.createObjectMessage(t);
        producer.send(message);
        return null;
    }

    public void sendMessageToActiveMQ(String queueName, String message) throws JMSException {
        MessageProducer producer = getProducer(queueName);
        TextMessage toSend = session.createTextMessage(message);
        producer.send(toSend);
    }
}

1 Producer for all destinations : 1个生产商,用于所有目的地:

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ConfigurationException;
import org.apache.log4j.Logger;

public class ActiveMQProducer2 {

    private static final Logger LOGGER = Logger.getLogger(ActiveMQProducer2.class);
    private Connection connection;
    private Session session;
    String activeMQConnection;
    Map<String, Destination> destinations = Collections.synchronizedMap(new HashMap<String, Destination>());
    private MessageProducer producer;
    Thread shutdownHook = new Thread(new Runnable() {
        @Override
        public void run() {
            close();
        }
    });

    public ActiveMQProducer2() throws ConfigurationException, JMSException {
        activeMQConnection = ActiveMQPropertyManagerFactory.getInstance().getString("active.mq.url");
        setupActiveMQ();
        Runtime.getRuntime().addShutdownHook(shutdownHook);
    }

    public void setupActiveMQ() throws JMSException {
        close();
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(activeMQConnection);
        factory.setRejectedTaskHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        connection = factory.createConnection();
        connection.start();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        producer = session.createProducer(session.createTemporaryQueue());
    }

    @Override
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }

    public void close() {
        if (connection != null) {
            try {
                connection.close();
            } catch (Exception e) {
            }
            connection = null;
        }
    }

    public void getConnection() throws JMSException {
        if (connection == null || session == null) {
            setupActiveMQ();
        }
    }

    public Destination getDestination(String queueName) throws JMSException {
        getConnection();
        Destination destination = destinations.get(queueName);
        if (destination == null) {
            destination = session.createQueue(queueName);
            destinations.put(queueName, destination);
        }
        return destination;
    }

    public <T extends Serializable> T sendToActiveMQ(String queueName, T t) throws JMSException {
        Destination destination = getDestination(queueName);
        ObjectMessage message = session.createObjectMessage(t);
        producer.send(destination, message);
        return null;
    }

    public void sendMessageToActiveMQ(String queueName, String message) throws JMSException {
        Destination destination = getDestination(queueName);
        TextMessage toSend = session.createTextMessage(message);
        producer.send(destination, toSend);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Apache Camel 从一个 ActiveMQ 实例上的多个队列中消费 - Apache Camel consuming from multiple queues on one ActiveMQ instance 通过同一ActiveMQConnectionFactory消耗多个ActiveMQ队列 - Consume multiple ActiveMQ queues via the same ActiveMQConnectionFactory 如何使用 ActiveMQ 5.x 检索 session 的创建主题(和队列) - How to retrieve created Topics (and Queues) of session with ActiveMQ 5.x 一个生产者,多个消费者 - One Producer, multiple Consumers 在两个ActiveMQ队列之间配置Apache Camel路由,以将生产者用于特定的目标队列,而不是使用未标识的生产者 - Configure an Apache Camel route between two ActiveMQ queues to use a producer for the specific destination queue rather than an unidentified producer 如何实现具有多个消费者和多个队列的消费者生产者 - How to implement consumer-producer with multiple consumers and multiple queues 跨多个队列的ActiveMQ消息组使用者选择吗? - ActiveMQ Message Group Consumer Selection Across Multiple Queues? 从JMS代码ActiveMQ将同一消息发布到多个队列 - Same message posted to multiple queues from JMS code ActiveMQ 生产者/消费者工作队列 - producer/consumer work queues ActiveMQ生产者生成heapdump - ActiveMQ producer generating heapdump
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM