MQ系列16:MQ实现消息过滤处理
MQ系列1:消息中间件执行原理
MQ系列2:消息中间件的技术选型
MQ系列3:RocketMQ 架构分析
MQ系列4:NameServer 原理解析
MQ系列5:RocketMQ消息的发送模式
MQ系列6:消息的消费
MQ系列7:消息通信,追求极致性能
MQ系列8:数据存储,消息队列的高可用保障
MQ系列9:高可用架构分析
MQ系列10:如何保证消息幂等性消费
MQ系列11:如何保证消息可靠性传输
MQ系列12:如何保证消息顺序性
MQ系列13:消息大量堆积如何为解决
MQ系列14:MQ如何做到消息延时处理
MQ系列15:MQ实现批量消息处理
1 背景
消息队列作为发布订阅模型的消息中间件广泛应用于上下游业务集成场景。在实际业务场景中,同一个主题下的消息往往会被多个不同的下游业务方处理,各下游的处理逻辑不同,只需要关注自身逻辑需要的消息子集。所以在 消息中心和消费者之间,需要有一种消息过滤功能,可以帮助消费者更高效地过滤自己需要的消息集合,避免大量无效消息投递给消费者,降低下游系统处理压力。
Apache RocketMQ 很好的支持了这一能力,它解决了单个业务域即同一个主题内不同消息子集的过滤问题。
2 关于消息过滤
2.1 概念
在消费者订阅了某个主题后,Apache RocketMQ 会将该主题中的所有消息投递给消费者。若消费者只需要关注部分消息,可通过设置过滤条件在 Apache RocketMQ 服务端进行过滤,只获取到需要关注的消息子集,避免接收到大量无效的消息。所以,过滤的本质就是将符合条件的消息投递给消费者,而不是将匹配到的消息过滤掉。
Apache RocketMQ 的消息过滤功能通过生产者和消费者对消息的属性、标签进行定义,并在 Apache RocketMQ 服务端根据过滤条件进行筛选匹配,将符合条件的消息投递给消费者进行消费。
2.2 消息过滤说明
2.2.1 原理介绍

备注:图片直接使用官网提供的
消息过滤主要通过以下几个关键流程实现:
- 生产者:生产者在初始化消息时预先为消息设置一些属性和标签,用于后续消费时指定过滤目标。
- 消费者:消费者在初始化及后续消费流程中通过调用订阅关系注册接口,向服务端上报需要订阅指定主题的哪些消息,即过滤条件。
- 服务端:消费者获取消息时会触发服务端的动态过滤计算,Apache RocketMQ 服务端根据消费者上报的过滤条件的表达式进行匹配,并将符合条件的消息投递给消费者。
2.2.2 消息过滤分类
Apache RocketMQ 支持Tag标签过滤和SQL属性过滤,这两种过滤方式对比如下:
| 对比项 | Tag标签过滤 | SQL属性过滤 |
|---|---|---|
| 过滤目标 | 消息的Tag标签。 | 消息的属性,包括用户自定义属性以及系统属性(Tag是一种系统属性)。 |
| 过滤能力 | 精准匹配。 | SQL语法匹配。 |
| 适用场景 | 简单过滤场景、计算逻辑简单轻量。 | 复杂过滤场景、计算逻辑较复杂。 |
2.3 Tag标签过滤
Tag标签过滤方式是 Apache RocketMQ 提供的基础消息过滤能力,基于生产者为消息设置的Tag标签进行匹配。生产者在发送消息时,设置消息的Tag标签,消费者需指定已有的Tag标签来进行匹配订阅。
Tag标签设置规则:
- Tag由生产者发送消息时设置,每条消息允许设置一个Tag标签。
- Tag使用可见字符,建议长度不超过128字符。
生产消息:发送的时候,需要设置Tag标签
Message message = messageBuilder.setTopic("topicTest")
//设置消息索引键,可根据关键字精确查找某条消息
.setKeys("msgKey")
//设置消息Tag,这样消费端可以根据Tag过滤消息
//该语句表示消息的Tag设置为"TagTest1"
.setTag("TagTest1")
// 设置消息体
.setBody("hello world!".getBytes())
.build();
订阅消息:匹配单个或者多个Tag标签。
String topic = "topicTest";
//1、第一种情况,只订阅消息标签为"TagTest1"的消息。
FilterExpression filterExpression = new FilterExpression("TagTest1", FilterExpressionType.TAG);
//2、第二种情况,订阅消息标签为"TagTest1"、"TagTest2"或"TagTest3"的消息。
FilterExpression filterExpression = new FilterExpression("TagTest1||TagTest2||TagTest3", FilterExpressionType.TAG);
pushConsumer.subscribe(topic, filterExpression);
如上,消费者可以限制接收包含 TagTest1 或 TagTest2 或 TagTest3 的消息,但是限制是一个消息只能有一个标签,这无法应对互联网复杂的应用场景。在这种情况下,可以在消息中设置一些属性,再使用SQL表达式通过筛选属性来筛选消息。下面我们看看怎么实现。
2.4 SQL属性过滤
SQL属性过滤是 RocketMQ 提供的高级消息过滤方式,通过生产者为消息设置的属性(Key)及属性值(Value)进行匹配。生产者在发送消息时可设置多个属性,消费者订阅时可设置SQL语法的过滤表达式过滤多个属性。
2.4.1 基本语法
RocketMQ只定义了一些基本语法来支持这个特性。你也可以很容易地扩展它。
- 数值比较,比如:>,>=,<,<=,BETWEEN,=;
- 字符比较,比如:=,<>,IN;
- IS NULL 或者 IS NOT NULL;
- 逻辑符号 AND,OR,NOT;
常量支持类型为:
- 数值,比如:123,3.1415;
- 字符,比如:‘abc’,必须用单引号包裹起来;
- NULL,特殊的常量
- 布尔值,TRUE 或 FALSE
只有使用push模式的消费者才能用使用SQL92标准的sql语句,接口如下:
public void subscribe(finalString topic, final MessageSelector messageSelector)
2.4.2 消息生产者
发送消息时,设置了消息Tag标签并定义了属性,用于做消息过滤
Message message = messageBuilder.setTopic("topicTest")
//设置消息索引键,可根据关键字精确查找某条消息
.setKeys("msgKey")
//设置消息Tag,这样消费端可以根据Tag过滤消息
//该语句表示消息的Tag设置为"TagTest1"
.setTag("TagTest1")
//消息也可以设置自定义的分类属性,比如下面这句话表示为消息自定义一个属性,该属性为性别,属性值为1(男)或者0(女)。
.addProperty("Sex", 1)
// 设置消息体
.setBody("hello world!".getBytes())
.build();
2.4.3 消息消费者
使用过滤表达式进行消息筛选,如下:
String topic = "topic";
//只订阅性别为1(男)的消息。
FilterExpression filterExpression = new FilterExpression("Sex IS NOT NULL AND Sex=1", FilterExpressionType.SQL92);
simpleConsumer.subscribe(topic, filterExpression);
//只订阅性别为1(男)且年龄大于18的消息。
FilterExpression filterExpression = new FilterExpression("Sex IS NOT NULL AND Age IS NOT NULL AND Sex = 1 AND Age > 18", FilterExpressionType.SQL92);
simpleConsumer.subscribe(topic, filterExpression);
//订阅所有消息
FilterExpression filterExpression = new FilterExpression("True", FilterExpressionType.SQL92);
simpleConsumer.subscribe(topic, filterExpression);
3 总结
Rocket MQ的消息过滤功能是在服务端进行的,可以根据消息的标签、属性等进行过滤。具体来说,Rocket MQ主要支持以下两种过滤方式:
TAG过滤:TAG是消息的业务标识,可以通过设置Tag表达式,判断消息是否包含指定的Tag,从而进行过滤。这种过滤方式简单直观,适用于基于Tag进行消息分类的场景。
SQL92过滤:可以使用SQL92表达式来灵活地过滤消息的Tag和属性。这种方式提供了更强大的过滤能力,可以根据复杂的条件进行消息筛选。
需要注意的是,Rocket MQ的消息过滤功能虽然强大,但是也会增加服务端的处理负担。因此,在使用时需要根据实际情况进行权衡,避免过度依赖消息过滤功能导致系统性能下降。
MQ系列16:MQ实现消息过滤处理的更多相关文章
- MQ系列5:RocketMQ消息的发送模式
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 在之前的篇章中,我们学习了RocketMQ的原理, ...
- MQ系列6:消息的消费
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 在之前 ...
- MQ系列8:数据存储,消息队列的高可用保障
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...
- MQ系列10:如何保证消息幂等性消费
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...
- MQ系列11:如何保证消息可靠性传输(除夕奉上)
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...
- MQ系列9:高可用架构分析
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...
- 【SpringBoot MQ 系列】RabbitMq 核心知识点小结
[MQ 系列]RabbitMq 核心知识点小结 以下内容,部分取材于官方教程,部分来源网络博主的分享,如有兴趣了解更多详细的知识点,可以在本文最后的文章列表中获取原地址 RabbitMQ 是一个基于 ...
- MQ系列3:RocketMQ 架构分析
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 1 背景 我们前面两篇对主流消息队列的基本构成和技术选型做了详细的分析.从本篇开始,我们会专注当下主流MQ之一的RocketMQ. 从 ...
- 【SpringBoot MQ 系列】RabbitListener 消费基本使用姿势介绍
[MQ 系列]RabbitListener 消费基本使用姿势介绍 之前介绍了 rabbitmq 的消息发送姿势,既然有发送,当然就得有消费者,在 SpringBoot 环境下,消费可以说比较简单了,借 ...
- 《吃透MQ系列》核心基础全在这里了
这是<吃透XXX>技术系列的开篇,这个系列的思路是:先找到每个技术栈最本质的东西,然后以此为出发点,逐渐延伸出其他核心知识.所以,整个系列侧重于思考力的训练,不仅仅是讲清楚 What,而是 ...
随机推荐
- NextJS项目的部署以及多环境的实现
背景 开发了个Next项目,将部署过程记录一下.另外由于项目准备了两个服务器分别作为开发自测的开发环境和交付给客户的生产环境使用:因此也介绍一下NextJS项目中多环境的配置. 项目结构 计划是让Ng ...
- 浅析switch和if(开发中这两者的优缺点;分析出优缺点在使用就能更确定自己需要使用哪个函数了)
分析 Switch 相较于 if 的优点 1.switch 执行效率 高于 if 的执行效率 分析: switch是在编译阶段将子函数的地址和判断条件绑定了,只要直接将a的直接映射到子函数地址去执 ...
- Python 爬虫实战:驾驭数据洪流,揭秘网页深处
爬虫,这个经常被人提到的词,是对数据收集过程的一种形象化描述.特别是在Python语言中,由于其丰富的库资源和良好的易用性,使得其成为编写爬虫的绝佳选择.本文将从基础知识开始,深入浅出地讲解Pytho ...
- BitLocker加密过程中断断电,能否恢复数据?
BitLocker是Windows系统提供的磁盘加密功能,用户自己可以手动开启.在访问受BitLocker保护的磁盘分区时,需要先提供正确的密码.秘钥或是BEK文件.如果使用BitLocker将系统盘 ...
- unity前后端通信
1. 配置请求体中的Json字符串 1 request_data = new RequestBodyClass(); 2 request_data.a = "Json第一个字段"; ...
- Harbor 容器镜像仓库
Harbor仓库概述 Docker官⽅提供了Registry镜像仓库,但是Registry的功能相对简陋.Harbor是VMware公司提供的⼀款镜像仓库,提供了权限控制.分布式发布.强⼤的安全扫描与 ...
- 【MAUI Blazor踩坑日记】1.关于图标的处理
前言 本系列文章,默认你已经踏上了MAUI Blazor的贼船,并且对MAUI Blazor有了一些了解,知道MAUI是什么,知道Blazor是什么. 不会教你怎么写MAUI Blazor的项目,只是 ...
- 【Leaflet专题篇】L.tileLayer图层顺序问题
1 问题复现 使用L.tileLayer加载底图(A.B.C)并使用layerControl管理.在用L.tileLayer.wms添加wms服务(D),当切换ABC时会压盖D视频中右下角的wms服务 ...
- openlayers学习笔记
https://www.cnblogs.com/suRimn/p/10649816.html
- nodejs端模块化方式comomjs详解
nodejs端实现模块化的方式通常是通过commonjs,使用模块化可以复用js代码,使得逻辑结构更为清晰. commonjs的语法规则如下通过 module.exports 或者 exports 导 ...