Java JMS使用多个主题

Java JMS使用多个主题,java,consumer,Java,Consumer,我是Java新手,正在从事一个使用多个(不同)主题并将其发送到另一台服务器的项目。我想知道处理多个主题的最佳方式是什么 据我所知,每个消费者都与一个主题相关,因此,如果我必须消费多个主题,那么每个不同的主题都需要一个消费者。由于使用者进行阻塞调用,我需要为每个使用者调用一个线程来并行地使用这些主题 如果我想进一步提高吞吐量,那么每个使用者有一个boss线程(附加到一个主题)并允许每个boss线程设置辅助线程以相应地提高性能是否是一种好的做法 如果这是一个良好的做法,请提供建议,如果不是,还有哪些

我是Java新手,正在从事一个使用多个(不同)主题并将其发送到另一台服务器的项目。我想知道处理多个主题的最佳方式是什么

据我所知,每个消费者都与一个主题相关,因此,如果我必须消费多个主题,那么每个不同的主题都需要一个消费者。由于使用者进行阻塞调用,我需要为每个使用者调用一个线程来并行地使用这些主题

如果我想进一步提高吞吐量,那么每个使用者有一个boss线程(附加到一个主题)并允许每个boss线程设置辅助线程以相应地提高性能是否是一种好的做法

如果这是一个良好的做法,请提供建议,如果不是,还有哪些其他选择?有什么众所周知的设计模式来处理这个问题吗

为什么我选择了消费者模型而不是听众模型


我还有一个限制,即消费者收到消息后,需要将消息发送到另一个接收服务器。如果接收服务器关闭(在新版本推送期间),则我必须暂停使用消息,直到接收服务器启动。在这种情况下,有一个消息侦听器没有帮助,因为当接收服务器关闭时,我无法暂停侦听器。我说的对吗?或者有没有办法暂停侦听器并在接收服务器启动之前停止使用消息?

我的方法是使用侦听器功能

对象实现了
MessageListener
接口,然后将消息侦听器添加到消费者。在这种情况下,客户端库将为您处理从队列读取消息并将其发送给侦听器的线程

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;

public class MyMessageConsumer implements MessageListener {

    public static void main() {
        try {

            MyMessageConsumer myMessageConsumer = new MyMessageConsumer();

            // This example is using the ActiveMQ client library
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("nio://localhost:61616");
            Connection connection = connectionFactory.createConnection();
            connection.start();

            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            Destination destination1 = session.createQueue("MyTopic1");
            MessageConsumer consumer1 = session.createConsumer(destination1);
            consumer1.setMessageListener(myMessageConsumer);

            Destination destination2 = session.createQueue("MyTopic2");
            MessageConsumer consumer2 = session.createConsumer(destination2);
            consumer2.setMessageListener(myMessageConsumer);

        } catch (Exception e) {
            System.out.println("Caught: " + e);
            e.printStackTrace();
        }
    }

    @Override
    public void onMessage(Message message) {
        // Handle my messages here
    }
}
会话事务

在这个选项中,我们使用事务性消息,如果调用session.rollback(),它将传递消息。操作成功时确认(),操作不成功时回滚()

包装io.bessel.test

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class MyMessageConsumer implements MessageListener {

    public static void main(String ... arguments) {
        try {
            // This example is using the ActiveMQ client library
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("nio://localhost:61616");
            Connection connection = connectionFactory.createConnection();
            connection.start();

            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);

            MyMessageConsumer myMessageConsumer = new MyMessageConsumer(session);

            Destination destination1 = session.createQueue("MyTopic1");
            MessageConsumer consumer1 = session.createConsumer(destination1);
            consumer1.setMessageListener(myMessageConsumer);

            Destination destination2 = session.createQueue("MyTopic2");
            MessageConsumer consumer2 = session.createConsumer(destination2);
            consumer2.setMessageListener(myMessageConsumer);

        } catch (Exception e) {
            System.out.println("Caught: " + e);
            e.printStackTrace();
        }
    }

    private final Session session;

    public MyMessageConsumer(Session session) {
        this.session = session;
    }

    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                String text = ((TextMessage) message).getText();
                System.out.println(String.format("Received message: %s", text));
                this.session.rollback();

            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }

}

我想用一个听者,但我没提到。我还有一个限制,即消费者收到消息后,需要将消息发送到另一个接收服务器。如果接收服务器关闭(在新版本推送期间),则我必须暂停使用消息,直到接收服务器启动。在这种情况下,有一个消息侦听器没有帮助,因为当接收服务器关闭时,我无法暂停侦听器。我说的对吗?或者有没有办法让听者暂停并停止使用消息,直到接收服务器启动?谢谢。为事务性消息添加了第二个代码示例。将反复重新传递消息,直到确认为止。这会在某些地方引入开销(就像所有事情一样),只是不确定它在哪里或是否会成为应用程序中的一个问题,但这是最直接的。