RocketMQ高级特性四-消息过滤

目录

前言

Broker端过滤

定义与概述

消息过滤分类

原理机制

使用场景

优缺点

Java代码示例 - Tag过滤

Java代码示例 - SQL92过滤 

客户端过滤

定义与概述

原理机制

使用场景

优缺点

Java代码示例

总结


前言

消息过滤是RocketMQ的一项高级特性,它允许消费者根据特定的条件来筛选感兴趣的消息,从而避免无关消息的处理,提升消费效率和性能。RocketMQ支持两种主要的消息过滤方式:Broker端过滤客户端过滤。注:文章中部分内容来源于Apache RocketMQ官网

Broker端过滤

定义与概述

Broker端过滤是指在Broker接收到消息后,基于消息的标签(Tag)或用户自定义属性进行过滤。只有满足过滤条件的消息才会被推送给消费者,从而减少消费者端的处理压力。

消息过滤分类
对比项Tag标签过滤SQL属性过滤
过滤目标消息的Tag标签。消息的属性,包括用户自定义属性以及系统属性(Tag是一种系统属性)。
过滤能力精准匹配。SQL语法匹配。
适用场景简单过滤场景、计算逻辑简单轻量。复杂过滤场景、计算逻辑较复杂。
原理机制
  • Tag过滤:每条消息可以带有一个或多个标签(Tag),消费者在订阅时可以指定感兴趣的标签,Broker只会将带有匹配标签的消息发送给消费者。这种方式过滤效率高,因为过滤逻辑是在Broker端实现的。

    例如,如果某条消息的标签是"TagA",消费者在订阅时指定只接收"TagA"的消息,那么只有这些消息会被推送到消费者。

  • SQL92过滤:RocketMQ支持使用SQL92标准的语法对消息属性进行过滤。开发者可以在消息发送时设置自定义属性,消费者在订阅时使用SQL92表达式进行筛选。此方式更灵活,可以基于多种条件进行复杂的过滤。

    例如,假设消息包含一个名为"age"的属性,消费者可以使用age > 30这样的SQL语句进行过滤。

使用场景
  • 高效消息消费:适用于有大量不同类型消息的场景,消费者只需处理特定类型的消息。例如,在订单系统中,不同的消费者可能只关注某些特定类型的订单消息。
  • 复杂过滤需求:在需要基于多条件组合进行消息筛选时,SQL92过滤提供了很大的灵活性。
优缺点
  • 优点

    • 减少网络流量:通过Broker端过滤,可以减少不必要的消息传输,降低网络带宽消耗。
    • 提高消费效率:消费者只需处理满足过滤条件的消息,减少了处理无关消息的开销。
  • 缺点

    • 处理复杂性增加:SQL92过滤需要消息带有自定义属性,增加了消息发送时的复杂性。
    • 配置管理复杂:需要在消费者订阅时配置过滤规则,且过滤规则复杂度较高时可能增加运维管理的难度。
Java代码示例 - Tag过滤
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;

public class TagFilterConsumer {
    public static void main(String[] args) throws MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.subscribe("TopicTest", "TagA || TagB");  // 只订阅TagA或TagB的消息

        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Received Message: %s%n", new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });

        consumer.start();
    }
}
Java代码示例 - SQL92过滤 
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;

public class SQLFilterConsumer {
    public static void main(String[] args) throws MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.subscribe("TopicTest", MessageSelector.bySql("age > 30"));

        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Received Message: %s%n", new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });

        consumer.start();
    }
}

客户端过滤

定义与概述

客户端过滤是指消息被发送到消费者后,由消费者在本地进行过滤。与Broker端过滤相比,客户端过滤的灵活性更高,因为消费者可以根据实际业务需求实现自定义的过滤逻辑。

原理机制
  • 消息接收后过滤:消费者接收到消息后,在处理逻辑中根据业务需求进行过滤。此种方式不依赖于Broker的过滤机制,而是在消费者端实现特定逻辑。

    例如,消费者可以在接收到消息后检查消息体的内容,决定是否处理该消息。

使用场景
  • 个性化过滤需求:适用于需要根据复杂业务逻辑进行过滤的场景。例如,根据消息体内容进行复杂的判断,而不是简单的标签或属性匹配。
  • 实时调整过滤规则:消费者可以在运行时动态调整过滤逻辑,适应变化的业务需求。
优缺点
  • 优点

    • 高度灵活:可以实现任何复杂的过滤逻辑,完全由消费者自行控制。
    • 动态调整:无需修改Broker配置,消费者可以随时根据业务需要调整过滤逻辑。
  • 缺点

    • 增加网络负载:所有消息都会被传输到消费者,增加了网络带宽的占用。
    • 效率较低:需要在客户端进行二次过滤,可能导致性能下降。
Java代码示例
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;

public class ClientFilterConsumer {
    public static void main(String[] args) throws MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.subscribe("TopicTest", "*");  // 订阅所有消息

        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                // 自定义过滤逻辑
                if (new String(msg.getBody()).contains("specificWord")) {
                    System.out.printf("Processing Message: %s%n", new String(msg.getBody()));
                    // 处理消息
                }
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });

        consumer.start();
    }
}

总结

RocketMQ的消息过滤机制为开发者提供了多种选择:

  • Broker端过滤适合需要高效过滤消息的场景,通过Tag或SQL92进行过滤,减少无关消息的传输和处理。
  • 客户端过滤适用于需要灵活、自定义过滤逻辑的场景,虽然增加了网络负载,但提供了更大的灵活性。

选择合适的过滤方式取决于具体的业务需求和系统架构,在实际应用中可以结合使用,以达到最佳的性能和功能平衡。

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值