RocketMQ Tag在实际业务中有什么作用?

开发
本文分析了 RocketMQ 的 Tag 功能,它在消息过滤和分类处理方面提供了极大的便利,适用于各种需要高效、低延迟消息传递的场景。

Tag 是 RocketMQ 提供的一种消息过滤机制,允许生产者在发送消息时指定一个或多个标签,消费者则可以根据这些标签来选择性地消费消息。这篇文章,我们将详细介绍 RocketMQ 中 Tag 的原理、源码分析以及示例。

Tag 的原理

在 RocketMQ 中,Tag 主要用于消息过滤。每个消息可以携带一个 Tag,消费者可以根据 Tag 来订阅特定的消息,从而实现消息的过滤和分类处理。

(1) 消息发送阶段

生产者在发送消息时,可以指定一个 Tag。这个 Tag 会被附加到消息的元数据中,并存储在 RocketMQ 的消息存储系统中。

(2) 消息存储阶段

消息被存储在 RocketMQ 的 Broker 中,消息的元数据(包括 Tag)也会被存储。

(3) 消息消费阶段

消费者在订阅消息时,可以指定要消费的 Tag。Broker 会根据消费者订阅的 Tag,将符合条件的消息投递给消费者。

(4) 源码分析

为了更好的理解 Tag的原理,我们通过 RocketMQ 中Tag 相关的几个主要代码片段进行演示。

生产者发送消息时的代码:

// 创建消息实例,并指定Topic和Tag
Message msg = new Message("TopicTest", "TagA", "Hello RocketMQ".getBytes());

// 发送消息
SendResult sendResult = producer.send(msg);

在 Message 类中,Tag 是通过构造函数传递的,并存储在 Message 对象的 tags 字段中。

消费者订阅消息时的代码:

// 创建消费者实例
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumerGroup");

// 订阅Topic,并指定Tag
consumer.subscribe("TopicTest", "TagA");

// 注册消息监听器
consumer.registerMessageListener(new MessageListenerConcurrently() {
    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
        for (MessageExt msg : msgs) {
            System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), new String(msg.getBody()));
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
});

// 启动消费者
consumer.start();

在 DefaultMQPushConsumer 类中,通过 subscribe 方法指定要订阅的 Topic 和 Tag,RocketMQ 内部会根据订阅的 Tag 进行消息过滤。

示例

下面是一个完整的示例,演示如何使用 RocketMQ 的 Tag 功能。

(1) 生产者代码

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class Producer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("producerGroup");
        producer.setNamesrvAddr("localhost:9876");

        // 启动生产者
        producer.start();

        // 发送消息
        for (int i = 0; i < 10; i++) {
            Message msg = new Message("TopicTest", "TagA", ("Hello RocketMQ " + i).getBytes());
            SendResult sendResult = producer.send(msg);
            System.out.printf("%s%n", sendResult);
        }

        // 关闭生产者
        producer.shutdown();
    }
}

(2) 消费者代码

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;

import java.util.List;

public class Consumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumerGroup");
        consumer.setNamesrvAddr("localhost:9876");

        // 订阅Topic,并指定Tag
        consumer.subscribe("TopicTest", "TagA");

        // 注册消息监听器
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                for (MessageExt msg : msgs) {
                    System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), new String(msg.getBody()));
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        // 启动消费者
        consumer.start();
        System.out.printf("Consumer Started.%n");
    }
}

尽管 RocketMQ 的 Tag 功能在消息过滤和分类处理方面提供了极大的便利,但也有其优缺点。下面详细分析一下:

优点

  • 简单易用:Tag 的使用非常简单,生产者只需在发送消息时指定 Tag,消费者在订阅消息时指定相应的 Tag 即可。
  • 高效过滤:通过 Tag 进行消息过滤,减少了消费者处理不相关消息的开销,从而提高了系统的性能。
  • 灵活性高:支持一个 Topic 下多个 Tag,使得消息的分类和过滤更加灵活。
  • 低延迟:Tag 过滤是在 Broker 端进行的,不会显著增加消息传递的延迟。
  • 减少网络带宽:消费者只会接收到自己感兴趣的消息,减少了不必要的网络传输,从而节省了带宽。

缺点

  • 单一维度过滤:Tag 只能提供单一维度的消息过滤,无法进行更复杂的多维度过滤。如果需要多维度过滤,需要结合其他机制(如消息属性)来实现。
  • 有限的灵活性:Tag 的数量和种类在设计阶段需要规划好,灵活性有限。如果后期需要添加新的 Tag,可能需要重新设计和部署。
  • 不支持复杂逻辑:Tag 过滤支持的逻辑较为简单,只能进行基于字符串匹配的过滤,无法支持复杂的过滤逻辑。
  • 管理复杂性:随着系统规模的增大,Tag 的管理和维护可能变得复杂,尤其是在多个应用共享同一个 Topic 的情况下。
  • 潜在的性能瓶颈:虽然 Tag 过滤在大多数场景下性能良好,但在极端情况下(如大量不同 Tag 的消息和高并发消费),可能会带来性能瓶颈。

适用场景

  • 日志和监控:不同类型的日志和监控数据可以通过 Tag 进行分类和过滤。
  • 电商系统:不同类型的订单、商品信息等可以通过 Tag 进行分类和过滤,消费者只处理自己感兴趣的消息。
  • 金融系统:不同类型的交易、通知等可以通过 Tag 进行分类和过滤,提高系统的处理效率。
  • 社交平台:不同类型的消息(如评论、点赞、私信等)可以通过 Tag 进行分类和过滤,提供更精准的消息推送。

总结

本文分析了 RocketMQ 的 Tag 功能,它在消息过滤和分类处理方面提供了极大的便利,适用于各种需要高效、低延迟消息传递的场景。然而,它也有一些局限性,如单一维度过滤、管理复杂性等。

在实际应用中,需要根据具体需求和系统设计,合理使用 Tag 功能,结合其他机制来实现更复杂的消息过滤和处理。

责任编辑:赵宁宁 来源: 猿java
相关推荐

2023-06-12 07:02:53

物联网数据决策

2019-04-28 17:39:06

大数据区块链数据隐私安全

2018-11-06 10:51:07

Redis开发存储系统

2022-03-02 14:08:35

区块链供应链技术

2009-12-03 18:21:15

软路由技术

2010-02-25 17:22:39

WCF服务行为

2010-01-14 10:35:34

VB.NET指针

2010-01-08 18:02:33

VB.NET事件

2010-01-15 13:30:53

VB.NET Tool

2023-06-25 11:38:31

2022-03-21 08:55:53

RocketMQ客户端过滤机制

2010-01-19 15:21:55

VB.NET区域性

2009-11-19 15:14:43

路由器系统

2010-01-07 16:16:03

VB.NET变量作用域

2009-11-23 17:56:45

业务路由器

2010-01-20 18:34:46

VB.NET Syst

2023-12-30 11:01:19

C语言C++编程

2024-01-02 17:11:09

数据分析运营

2018-02-01 16:34:54

点赞
收藏

51CTO技术栈公众号