ActiveMQ--Topic与queue传递方式的demo

在点对点的消息传递时,目的地称为 队列 queue

在发布订阅消息传递中,目的地称为 主题 topic

一、简介JMS规范

JMS : Java 消息中间件的服务接口规范,activemq 之上是 mq , 而 mq 之上是JMS 定义的消息规范 。 activemq 是mq 技术的一种理论实现(与之相类似的实现还有 Kafka RabbitMQ RockitMQ ),而 JMS 是更上一级的规范。

JMS规范编码的总体架构

 

在点对点的消息传递时,目的地(Destination)称为 队列 queue

在发布订阅消息传递中,目的地(Destination)称为 主题 topic

二、生产者消费者的demo

生产者

 

public class JmsProduce {
            //  linux 上部署的activemq 的 IP 地址 + activemq 的端口号
    public static final String ACTIVEMQ_URL = "tcp://192.168.17.3:61616";
    public static final String QUEUE_NAME = "queue01";
    
    public static void main(String[] args) throws  Exception{
        
        // 1 按照给定的url创建连接工程,这个构造器采用默认的用户名密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        // 2 通过连接工厂连接 connection  和 启动
        javax.jms.Connection connection = activeMQConnectionFactory.createConnection();
        //  启动
        connection.start();
        // 3 创建回话  session
        // 两个参数,第一个事务, 第二个签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        // 4 创建目的地 (两种 : 队列/主题   这里用队列)
        Queue queue = session.createQueue(QUEUE_NAME);
        // 5 创建消息的生产者
        MessageProducer messageProducer = session.createProducer(queue);
        // 6 通过messageProducer 生产 3 条 消息发送到消息队列中
        for (int i = 1; i < 4 ; i++) {
            // 7  创建字消息
            TextMessage textMessage = session.createTextMessage("msg--" + i);
            // 8  通过messageProducer发布消息
            messageProducer.send(textMessage);
        }
        // 9 关闭资源
        messageProducer.close();
        session.close();
        connection.close();

        System.out.println("  **** 消息发送到MQ完成 ****");
    }
}

执行过后:

 证明消息生产成功

与之相对应的消息消费者(处理消息的系统)代码及运行

public class JmsConsumer {
    public static final String ACTIVEMQ_URL = "tcp://192.168.17.3:61616";
    public static final String QUEUE_NAME = "queue01";   // 1对1 的队列

    public static void main(String[] args) throws Exception{
        // 1 按照给定的url创建连接工程,这个构造器采用默认的用户名密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        // 2 通过连接工厂连接 connection  和 启动
        javax.jms.Connection connection = activeMQConnectionFactory.createConnection();
        //  启动
        connection.start();
        // 3 创建回话  session
        // 两个参数,第一个事务, 第二个签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        // 4 创建目的地 (两种 : 队列/主题   这里用队列)
        Queue queue = session.createQueue(QUEUE_NAME);
        // 5 创建消息的消费者
        MessageConsumer messageConsumer = session.createConsumer(queue);
        while(true){
            // 这里是 TextMessage 是因为消息发送者是 TextMessage , 接受处理的
            // 也应该是这个类型的消息
            TextMessage message = (TextMessage)messageConsumer.receive();
            if (null != message){
                System.out.println("****消费者的消息:"+message.getText());
            }else {
                break;
            }
        }
        messageConsumer.close();
        session.close();
        connection.close();
    }
}

 

这个代表有一个消息消费者处理消息,并且处理了三条消息,待处理的消息变为了0

 

在消费者去处理消息时,也可以不通过recieve进行阻塞式的获取消息,可以通过一种监听器的方式

// 通过监听的方式来消费消息
  // 通过异步非阻塞的方式消费消息
  // 通过messageConsumer 的setMessageListener 注册一个监听器,
  // 当有消息发送来时,系统自动调用MessageListener 的 onMessage 方法处理消息
  messageConsumer.setMessageListener(new MessageListener() {   // 可以用监听器替换之前的同步receive 方法
      public void onMessage(Message message)  {
              if (null != message  && message instanceof TextMessage){
                  TextMessage textMessage = (TextMessage)message;
                  try {
               System.out.println("****消费者的消息:"+textMessage.getText());
              }catch (JMSException e) {
                      e.printStackTrace();
                  }
          }
      }
  });

此处以queue为例,topic类似,只需要通过改变session创建的消息模式即可。

这里的一点经验: activemq 好像自带负载均衡,当先启动两个队列(Queue)的消费者时,在启动生产者发出消息,此时的消息平均的被两个消费者消费。 并且消费者不会消费已经被消费的消息(即为已经出队的消息)

但是当有多个主题(Topic)订阅者时,

先要有订阅者,生产者才有意义。

发布者发布的消息,每个订阅者都会接收所有的消息。topic 更像是被广播的消息,但是缺点是不能接受已经发送过的消息。且在这种发布订阅模式下,如果不进行持久化处理,默认情况是必须要订阅者先订阅,发布者再去发布才可收到消息,且订阅者下线再上线的话也无法继续接收到不在线时发布的消息。

Topic模式队列和Queue模式队列的区别

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值