activemq如何保证消息按顺序消费

生产者消费者模式/点到点模式/队列模式:

即生产者生产若干消息,由若干消费者共同消费消息,消息不重复消费。

 

发布订阅模式/主题模式:(pub/sub)

生产者生产若干消息,每个消费者都消费全部的消息。

 

独占消息模式:

只有一个消费者在消费消息,其他消费者干瞪眼,当消费者挂掉后才会由下一个消费者接着消费。

 

 

activemq简单写出生产者和消费者步骤:(发布订阅模式有代码例子)

生产者:

1.创建ConnectionFactory

2.创建Connection

3.启动连接

4.创建会话

5.创建一个目标

6.创建一个生产者

7.创建消息

8.发布消息

9.关闭连接

 

消费者:

1.创建连接工厂connectionfactory

2.创建连接

3.启动连接

4.创建会话

5.创建一个目标

6.创建一个消费者

7.创建一个监听器

 

activemq中的消息独占模式也是队列模式中的一种。

activemq消费模式中消息独占模式可以保证消息按照顺序消费,这种模式即使是在集群模式中,也只有一个节点在进行消息的消费,其他节点不进行消费,当正在消费的节点挂掉了,才会启用第二个节点进行消费,所以多节点中其他节点只能做备用,效率自然也就只有一个节点的效率了。

 

producer发送消息是有先后顺序的,这种顺序保持到了broker中。如果希望消息按顺序被消费掉,则应该把消息投送给单独一个consumer。如果队列只有一个consumer,那就很ok了,broker没有选择。但是,一旦唯一的consumer挂了,会造成服务不可用。因此出现了exclusive consumer,配置如下:

new ActiveMQQueue("TEST.QUEUENAME?consumer.exclusive=true");

也可以在监听注解那里加上:

@JmsListener(destination = "test.ruby.queue?consumer.exclusive=true")

 

如果有2个consumer都是这样配置的,broker只会把队列消息发送给其中一个consumer,如果这个consumer挂掉了,broker会把消息推送给另外的consumer,这样就保证了按顺序消费消息。

 

这种消息独占模式消费模式只有一个节点可以正常接收消息,其他节点只能作为备用,所以即使部署的是集群多节点消费者,实际上干活消费的只有一个消费者,自然效率和处理速度也就只有一个节点的效率和速度了。

 

源码解析:

https://www.cnblogs.com/allenwas3/p/8652484.html

https://blog.csdn.net/yaoqinggg/article/details/82563304

 

 

发布订阅模式:

生产者生产的消息会被每一个消费者消费一遍,即每个消费者都会消费生产者的所有消息。不过,消费者必须提前启动,启动后才可以消费此时生产者发送的消息,启动前的消息不消费,即消费者不能消费订阅之前就发送到主题中的消息。

代码例子:

消费者:

package com.mq.ruby.publishsubscribe;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**

* 主题模式

* 也是发布订阅模式

* 消费者

*/

public class AppConsumer {

private static final String url = "tcp://127.0.0.1:61616";

private static final String topicName = "topic-ceshi";

private static final String userName = "admin";

private static final String passWord = "admin";

public static void main(String[] args) throws Exception{

//1.创建连接工厂connectionfactory

ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(userName, passWord, url);

//2.创建连接

Connection connection = activeMQConnectionFactory.createConnection();

//3.启动连接

connection.start();

//4.创建会话

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

//5.创建一个目标

//队列模式

Destination queue = session.createQueue(topicName);

//主题模式

Destination topic = session.createTopic(topicName);

//6.创建一个消费者

MessageConsumer consumer = session.createConsumer(topic);

//7.创建一个监听器

consumer.setMessageListener(new MessageListener() {

@Override

public void onMessage(Message message) {

try {

System.out.println("接收消息为:"+((TextMessage)message).getText());

} catch (JMSException e) {

e.printStackTrace();

}

}

});

//8.关闭连接

// connection.close();

}

}

 

 

生产者:

package com.mq.ruby.publishsubscribe;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**

* 主题模式

* 也是发布订阅模式

* 生产者

*/

public class AppProducer {

private static final String url = "tcp://127.0.0.1:61616";

private static final String topicName = "topic-ceshi";

private static final String userName = "admin";

private static final String passWord = "admin";

public static void main(String[] args) throws Exception {

//1.创建ConnectionFactory

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(userName,passWord,url);

//2.创建Connection

Connection connection = connectionFactory.createConnection();

//3.启动连接

connection.start();

//4.创建会话

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

//5.创建一个目标

//队列模式

Destination queue = session.createQueue(topicName);

//主题模式

Destination destination = session.createTopic(topicName);

//6.创建一个生产者

MessageProducer producer = session.createProducer(destination);

for (int i = 0; i<10; i++) {

//7.创建消息

TextMessage textMessage = session.createTextMessage("test" + i);

//8.发布消息

producer.send(textMessage);

System.out.println("生产者发送消息:"+textMessage.getText());

}

//9.关闭连接

connection.close();

}

}

感觉写的有点乱糟糟的,谢谢大家评论指出不足

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值