RocketMQ笔记(九)SpringBoot整合RocketMQ消息过滤

本文详细介绍了ApacheRocketMQ中的消息过滤功能,包括Tag标签过滤和SQL属性过滤,涉及消费者配置、maven依赖以及示例代码。展示了如何通过Tag标签进行精确和多条件匹配,以及如何使用SQL表达式进行复杂条件筛选。
摘要由CSDN通过智能技术生成

一、简介

  过滤的含义指的是将符合条件的消息投递给消费者,而不是将匹配到的消息过滤掉。

  Apache RocketMQ 的消息过滤功能通过生产者和消费者对消息的属性、标签进行定义,并在 Apache RocketMQ 服务端根据过滤条件进行筛选匹配,将符合条件的消息投递给消费者进行消费。

1.1、消息过滤分类

  在 RocketMQ 中,有两种用于消息过滤的两种选择器类型:

  • Tag标签过滤:表示按照消息的标签(Tag)进行消息过滤。消息发送时可以为消息设置一个或多个标签,消费者可以通过订阅特定的标签来选择性地接收消息。当消费者订阅了特定标签的消息时,只有带有匹配标签的消息才会被消费者接收。
  • SQL属性过滤:表示按照类似 SQL 的语法进行消息过滤。通过 SQL92 表达式,消费者可以根据消息的属性或标签进行更复杂的条件过滤。例如,可以根据消息的属性值、标签、消息键等进行条件过滤,以实现更精细化的消息过滤需求。

  这两种选择器类型可以根据实际需求选择合适的方式进行消息过滤。Tag标签过滤 更加简单直观,适用于基本的消息过滤需求;而 SQL属性过滤 则更加灵活强大,适用于复杂的消息过滤场景

二、消息过滤

2.1、消费者maven依赖

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rocketmq</artifactId>
        <groupId>com.alian</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>10-filter-message</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.alian</groupId>
            <artifactId>common-rocketmq-dto</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

2.2、application配置

application.properties

server.port=8010

# rocketmq地址
rocketmq.name-server=192.168.0.234:9876
# 默认的消费者组
rocketmq.consumer.group=FILTER_CONSUMER_GROUP
# 批量拉取消息的数量
rocketmq.consumer.pull-batch-size=10
# 集群消费模式
rocketmq.consumer.message-model=CLUSTERING

  实际上对于本文来说,下面两个配置不用配置,也不会生效。

# 默认的消费者组
rocketmq.consumer.group=BROADCASTING_CONSUMER_GROUP
# 广播消费模式
rocketmq.consumer.message-model=CLUSTERING

  因为优先的是@RocketMQMessageListener 注解中设置 consumerGroupmessageModel 参数。

2.3、Tag标签过滤

  Tag标签过滤为精准字符串匹配,过滤规则设置格式如下:

  • 单Tag匹配:过滤表达式为目标Tag。表示只有消息标签为指定目标Tag的消息符合匹配条件,会被发送给消费者。
  • 多Tag匹配:多个Tag之间为或的关系,不同Tag间使用两个竖线(||)隔开。例如,Tag1||Tag2||Tag3,表示标签为Tag1或Tag2或Tag3的消息都满足匹配条件,都会被发送给消费者进行消费。
  • 全部匹配:使用星号(*)作为全匹配表达式。表示主题下的所有消息都将被发送给消费者进行消费。
@Slf4j
@Service
@RocketMQMessageListener(topic = "tag_filter_string_message_topic",
        consumerGroup = "FILTER_GROUP_STRING",
        selectorType = SelectorType.TAG,
        selectorExpression = "Golang || go")
public class TagStringMessageConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        // 发送方在批量发送服务
        log.info("Tag标签过滤接收到的消息: {}", message);
        // 处理消息的业务逻辑
    }
}

  生产者我就复用前面批量消息发送的模块了,只不过我们发送消息的topic中加入了标签:格式是:topic标签值,具体见代码:

    @Test
    public void syncSendBatchTagStringMessagesWithBuilder() {
        // 计算过期时间戳
        String[] tags = new String[]{"java", "go", "Golang", "vue", "react"};
        String topic = "tag_filter_string_message_topic";
        for (int i = 0; i < 5; i++) {
            String message = "我是一条Tag过滤消息下标:" + tags[i];
            Message<String> rocketMessage = MessageBuilder.withPayload(message).build();
            SendResult sendResult = rocketMQTemplate.syncSend(topic + ":" + tags[i], rocketMessage);
            log.info("同步发送Tag标签信息结果:{}", sendResult);
        }
    }

运行结果:

[_GROUP_STRING_1] c.alian.filter.TagStringMessageConsumer  : Tag标签过滤接收到的消息: 我是一条Tag过滤消息下标:go
[_GROUP_STRING_2] c.alian.filter.TagStringMessageConsumer  : Tag标签过滤接收到的消息: 我是一条Tag过滤消息下标:Golang

2.4、SQL属性过滤

  我觉得阁下大有可能会报错,您不烦先给broker.conf的配置文件先配置上:enablePropertyFilter=true,然后重启broker。

@RocketMQMessageListener(topic = "filter_string_message_topic",
        consumerGroup = "FILTER_GROUP_STRING",
        selectorType = SelectorType.SQL92,
        selectorExpression = "pos>=3")
public class StringMessageConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        // 发送方在批量发送服务
        log.info("SQL属性过滤接收到的消息: {}", message);
        // 处理消息的业务逻辑
    }
}

单元测试

    @Test
    public void syncSendBatchSqlStringMessagesWithBuilder() {
        String topic = "sql_filter_string_message_topic";
        for (int i = 0; i < 5; i++) {
            String message = "我是一条sql过滤消息下标:" + i;
            Message<String> rocketMessage = MessageBuilder.withPayload(message)
                    .setHeader("pos", i)
                    .build();
            rocketMQTemplate.convertAndSend(topic, rocketMessage);
        }
    }

运行结果:

[_GROUP_STRING_1] c.alian.filter.SqlStringMessageConsumer  : SQL属性过滤接收到的消息: 我是一条sql过滤消息下标:3
[_GROUP_STRING_2] c.alian.filter.SqlStringMessageConsumer  : SQL属性过滤接收到的消息: 我是一条sql过滤消息下标:4

三、附录

3.1、SQL属性过滤规则

  RocketMQ 通过消费者组(Consumer Group)来维护不同消费者的消费进度。每个消费

语法说明示例
IS NULL判断属性不存在a IS NULL :属性a不存在
IS NOT NULL判断属性存在a IS NOT NULL:属性a存在
> >= < <=用于比较数字,不能用于比较字符串,否则消费者客户端启动时会报错。 说明 可转化为数字的字符串也被认为是数字。a IS NOT NULL AND a > 100:属性a存在且属性a的值大于100。 a IS NOT NULL AND a > ‘abc’:错误示例,abc为字符串,不能用于比较大小。
BETWEEN xxx AND xxx用于比较数字,不能用于比较字符串,否则消费者客户端启动时会报错。等价于>= xxx AND <= xxx。表示属性值在两个数字之间a IS NOT NULL AND (a BETWEEN 10 AND 100):属性a存在且属性a的值大于等于10且小于等于100
NOT BETWEEN xxx AND xxx用于比较数字,不能用于比较字符串,否则消费者客户端启动会报错。等价于< xxx OR > xxx,表示属性值在两个值的区间之外a IS NOT NULL AND (a NOT BETWEEN 10 AND 100):属性a存在且属性a的值小于10或大于100
IN (xxx, xxx)表示属性的值在某个集合内。集合的元素只能是字符串a IS NOT NULL AND (a IN (‘abc’, ‘def’)):属性a存在且属性a的值为abc或def
= <>等于和不等于。可用于比较数字和字符串a IS NOT NULL AND (a = ‘abc’ OR a<>‘def’):属性a存在且属性a的值为abc或a的值不为def
AND OR逻辑与、逻辑或。可用于组合任意简单的逻辑判断,需要将每个逻辑判断内容放入括号内a IS NOT NULL AND (a > 100) OR (b IS NULL):属性a存在且属性a的值大于100或属性b不存在
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值