ActiveMQ消费者和生成者——点对点模式、发布/订阅模式

        ActiveMQ中一般有两种消息队列,一是点对点模式(p2p),二是发布/订阅模式(pub/sub)。

        在进行demo测试之前,我们先建立一个maven工程,引入相应的包:

<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-all</artifactId>
    <version>5.15.10</version>
</dependency>

或者

<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-client</artifactId>
    <version>5.15.10</version>
</dependency>

        点对点模式:

        点对点的模式主要建立在一个队列上面,当连接一个列队的时候,发送端不需要知道接收端是否正在接收,可以直接向ActiveMQ发送消息,发送的消息,将会先进入队列中,如果有接收端在监听,则会发向接收端,如果没有接收端接收,则会保存在ActiveMQ服务器,直到接收端接收消息,点对点的消息模式可以有多个发送端,多个接收端,但是一条消息,只会被一个接收端给接收到,哪个接收端先连上ActiveMQ,则会先接收到,而后来的接收端则接收不到那条消息。

        我们先建立一个生产者:


public class QueueProducer {
    public static void main(String[] args) throws Exception {
        // 1.创建连接工厂,服务器ip记得修改为自己的,端口号是61616,不是ActiveMQ服务器的端口号8161
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.232.135:61616");
        // 2.获取连接
        Connection connection = connectionFactory.createConnection();
        // 3.启动连接
        connection.start();
        // 4.获取session (参数1:是否启动事务,参数2:消息确认模式)
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        // 5.创建队列对象
        Queue queue = session.createQueue("test-queue");
        // 6.创建消息生产者
        MessageProducer producer = session.createProducer(queue);
        // 7.创建消息
        TextMessage textMessage = session.createTextMessage("点对点消息队列测试");
        // 8.发送消息
        producer.send(textMessage);
        // 9.关闭资源
        producer.close();
        session.close();
        connection.close();
        System.out.println("消息生产成功.....");
    }
}

        接着建立消费者:


public class QueueConsumer {
    public static void main(String[] args) throws JMSException, IOException {
            //1.创建连接工厂
            ConnectionFactory connectionFactory=new ActiveMQConnectionFactory("tcp://192.168.232.135:61616");
            //2.获取连接
            Connection connection = connectionFactory.createConnection();
            //3.启动连接
            connection.start();
            //4.获取session  (参数1:是否启动事务,参数2:消息确认模式)
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            //5.创建队列对象
            Queue queue = session.createQueue("test-queue");
            //6.创建消息消费
            MessageConsumer consumer = session.createConsumer(queue);
            //7.监听消息
            consumer.setMessageListener(new MessageListener() {
                public void onMessage(Message message) {
                    TextMessage textMessage=(TextMessage)message;
                    try {
                        System.out.println("接收到消息:"+textMessage.getText());
                    } catch (JMSException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });
    }
}

        我们这里是将消费者使用异步监听的方式进行监听的,也就是使用的是MessageConsumer中的setMessageListener(MessageListener listener) ,还有一种方式是使用同步的方法,也就是MessageConsumer中的recive(),只需要把第7步监听消息修改为consumer.recive()即可。

        我们先启动生产者,这时候我们查看ActiveMQ服务器中的Queues可以发现生产了一条消息:

        接着启动消费者,可以看到会直接把此消息给消费掉:

        如果我们同时启动两个消费者,然后让生产者多生产几条消息,我们通过控制台可以发现,每条消息只会被一个消费者接收过来消费,关于消费者之间如何确定谁去消费,后期我会详细解释,这里只做简单的介绍。

        发布/订阅模式:

        在发布/订阅消息模型中,发布者发布一个消息,该消息通过Topic传递给所有的客户端。该模式下,发布者与订阅者都是匿名的,即发布者与订阅者都不知道对方是谁。并且可以动态的发布与订阅Topic。Topic主要用于保存和传递消息,且会一直保存消息直到消息被传递给客户端。一个消息可以被多个消费者给消费掉,但只有当你订阅后才会去消费,订阅之前的消息都不会被消费。

        首先建立生成者:

public class TopicProducer {
    public static void main(String[] args) throws JMSException {
        //1.创建连接工厂
        ConnectionFactory connectionFactory=new ActiveMQConnectionFactory("tcp://192.168.232.135:61616");
        //2.获取连接
        Connection connection = connectionFactory.createConnection();
        //3.启动连接
        connection.start();
        //4.获取session  (参数1:是否启动事务,参数2:消息确认模式)
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //5.创建主题对象
        Topic topic = session.createTopic("test-topic");
        //6.创建消息生产者
        MessageProducer producer = session.createProducer(topic);
        //7.创建消息
        TextMessage textMessage = session.createTextMessage("发布/订阅模式消息队列");
        //8.发送消息
        producer.send(textMessage);
        //9.关闭资源
        producer.close();
        session.close();
        connection.close();
    }
}

        接着我们来建立消费者:


public class TopicConsumer {
    public static void main(String[] args) throws JMSException {
        //1.创建连接工厂
        ConnectionFactory connectionFactory=new ActiveMQConnectionFactory("tcp://192.168.232.135:61616");
        //2.获取连接
        Connection connection = connectionFactory.createConnection();
        //3.启动连接
        connection.start();
        //4.获取session  (参数1:是否启动事务,参数2:消息确认模式)
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //5.创建主题对象
        //Queue queue = session.createQueue("test-queue");
        Topic topic = session.createTopic("test-topic");
        //6.创建消息消费
        MessageConsumer consumer = session.createConsumer(topic);
        //7.监听消息
        consumer.setMessageListener(new MessageListener() {
            public void onMessage(Message message) {
                TextMessage textMessage=(TextMessage)message;
                try {
                    System.out.println("接收到消息:"+textMessage.getText());
                } catch (JMSException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
}

        开启生产者,然后打开ActiveMQ的Topics界面,我们可以看到创建了一条消息:

        接着打开消费者,此时我们会发现,消息并没有被消费掉,因为我们是先用生产者发布消息,再让消费者进行订阅的,所以此时并没有被消费掉。

        如果我们再启动生产者生产一条消息,此时是会被消费者消费掉的:

        如果我们再启动一个消费者,然后让生产者再发布一条消息,我们会发现这条消息被这两个消费者都消费掉,也就是这两个消费者都会去消费这条消息:

        整个工作流程如下:

        ①创建工厂ConnectionFactary

        ②通过工厂获取连接Connection

        ③启动连接

        ④通过连接获取会话Session

        ⑤通过会话创建队列Queue(点对点)或者订阅Topic(订阅)

        ⑥通过会话创建创建消息生产者

        ⑦创建消息

        ⑧发送或接收(注册监听)消息

        ⑨关闭连接

        在消费者中可以不要第⑨步,因为关闭了的话,在使用异步的方式的时候,即MessageConsumer中的setMessageListener(MessageListener listener)是没法进行消息消费的。就算是使用同步的方式,即MessageConsumer中的receive()时,也是只能启动一次消费一条消息。

        通过这两种模式的操作,我们应该能发现这两者的不同之处,点对点是不管消息是否先生产,只要最后有消费者,就能被成功消费,而发布/订阅模式中,只有在消息被订阅后,才会被消费,在订阅之前的消息,都不会被消费掉。

发布了165 篇原创文章 · 获赞 41 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_41061437/article/details/100636461