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,而是 ...
随机推荐
- 基于 NNCF 和 🤗 Optimum 面向 Intel CPU 对 Stable Diffusion 优化
基于隐空间的扩散模型 (Latent Diffusion Model),是解决文本到图片生成问题上的颠覆者.Stable Diffusion 是最著名的一例,广泛应用在商业和工业.Stable Dif ...
- 【原创】从Ubuntu-base构建ubuntu rootfs系统(以x86_64和arm为例)
版权声明:本文为本文为博主原创文章,转载请注明出处,博客地址:https://www.cnblogs.com/wsg1100/.如有错误,欢迎指正. 目录 1.介绍 2.目的 2.准备宿主系统 2.1 ...
- Java原生图片Base64转码与Base64解码
原文地址 import org.apache.commons.codec.binary.*; import java.io.*; import java.net.*; /** * 将file文件转换为 ...
- C#获取文件MD5
什么是MD5? MD5 Message-Digest Algorithm,MD5信息摘要算法.一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于 ...
- JVM虚拟机栈
JVM虚拟机栈 1.概述 1.1背景 由于跨平台性的设计,Java的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降 ...
- Nginx获取用户真实IP
Nginx获取用户真实IP地址 本人在一次项目中,使用Nginx需要获取到用户IP,本来可以很常规的获取的,可现实往往不常规,项目是前后端分离的,部署时,前端使用了Nginx进行了代理并转发,后端也使 ...
- K8S 对象
本页说明了在 Kubernetes API 中是如何表示 Kubernetes 对象的, 以及使用 .yaml 格式的文件表示 Kubernetes 对象. https://kubernetes.io ...
- HBase Compaction 原理与线上调优实践
作者:vivo 互联网存储技术团队- Hang Zhengbo 本文对 HBase Compaction 的原理.流程以及限流的策略进行了详细的介绍,列举了几个线上进行调优的案例,最后对 Compac ...
- 钟表练习 html+css实现
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- nodejs中如何使用http创建一个服务
http模块是nodejs中非常重要的一部分,用于开启一个服务,我们可以用它自定义接口供客户端使用. 开启服务的方式也比较简单,几行代码就可以搞定 const http = require('ht ...