JMS使用多个主题

时间:2016-03-01 06:02:44

标签: java consumer

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

根据我的理解,每个消费者都与一个主题联系在一起,所以如果我不得不消费多个主题,那么每个不同主题需要一个消费者。由于消费者进行阻塞调用,我需要为每个消费者调用一个线程来并行使用这些主题。

如果我想进一步提高吞吐量,那么每个消费者拥有一个boss线程(附加到主题)是一个好习惯,并允许每个boss线程设置工作线程以相应地提高性能?

如果这是一个好的做法,请告知,如果不是,那么其他选择是什么?是否有任何众所周知的设计模式来处理这个问题

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

我还有一个约束,即在消费者收到消息后需要将消息发送到另一个接收服务器。如果接收服务器已关闭(在新版本推送期间),那么我必须暂停消费消息,直到接收服务器启动。在这种情况下,有一个消息监听器将无济于事,因为我不能在接收服务器关闭时暂停监听器。当我说这个或者有没有办法暂停监听器并停止消息消息直到接收服务器启动时,我是对的吗?

1 个答案:

答案 0 :(得分:1)

我要采用的方法是使用监听器功能。

您的对象实现了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(),它将传递消息。您确认()当您的操作成功时,或者当它不是时回滚()。

package 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();
            }
        }
    }

}