这些MQ概念你都懂吗:死信队列、重试队列、消息回溯等

开发 前端
消息队列(MQ)的基本概念,很多时候都要了解清楚,这样在学消息队列中间件就比较能够游刃有余,遇到不清楚的也可以重新翻来看看,加深理解。

[[335625]]

本文转载自微信公众号「搬运工来架构」,作者cocodroid 。转载本文请联系搬运工来架构公众号。

消息队列(MQ)的基本概念,很多时候都要了解清楚,这样在学消息队列中间件就比较能够游刃有余,遇到不清楚的也可以重新翻来看看,加深理解。这里有关于:优先级队列、延迟队列、死信队列、重试队列、消息回溯、消息堆积、消息追踪/消息轨迹、消息过滤、消息审计、消息路由等的介绍。

01.优先级队列

优先级队列不同于先进先出队列,优先级高的消息具备优先被消费的特权,这样可以为下游提供不同消息级别的保证。不过这个优先级也是需要有一个前提的:如果消费者的消费速度大于生产者的速度,并且消息中间件服务器(一般简单的称之为Broker)中没有消息堆积,那么对于发送的消息设置优先级也就没有什么实质性的意义了,因为生产者刚发送完一条消息就被消费者消费了,那么就相当于Broker中至多只有一条消息,对于单条消息来说优先级是没有什么意义的。

02.延迟队列

当你在网上购物的时候是否会遇到这样的提示:“三十分钟之内未付款,订单自动取消”?这个是延迟队列的一种典型应用场景。延迟队列存储的是对应的延迟消息,所谓“延迟消息”是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。延迟队列一般分为两种:基于消息的延迟和基于队列的延迟。基于消息的延迟是指为每条消息设置不同的延迟时间,那么每当队列中有新消息进入的时候就会重新根据延迟时间排序,当然这也会对性能造成极大的影响。实际应用中大多采用基于队列的延迟,设置不同延迟级别的队列,比如5s、10s、30s、1min、5mins、10mins等,每个队列中消息的延迟时间都是相同的,这样免去了延迟排序所要承受的性能之苦,通过一定的扫描策略(比如定时)即可投递超时的消息。

03.死信队列

由于某些原因消息无法被正确的投递,为了确保消息不会被无故的丢弃,一般将其置于一个特殊角色的队列,这个队列一般称之为死信队列。与此对应的还有一个“回退队列”的概念,试想如果消费者在消费时发生了异常,那么就不会对这一次消费进行确认(Ack),进而发生回滚消息的操作之后消息始终会放在队列的顶部,然后不断被处理和回滚,导致队列陷入死循环。为了解决这个问题,可以为每个队列设置一个回退队列,它和死信队列都是为异常的处理提供的一种机制保障。实际情况下,回退队列的角色可以由死信队列和重试队列来扮演。

04.重试队列

重试队列其实可以看成是一种回退队列,具体指消费端消费消息失败时,为防止消息无故丢失而重新将消息回滚到Broker中。与回退队列不同的是重试队列一般分成多个重试等级,每个重试等级一般也会设置重新投递延时,重试次数越多投递延时就越大。举个例子:消息第一次消费失败入重试队列Q1,Q1的重新投递延迟为5s,在5s过后重新投递该消息;如果消息再次消费失败则入重试队列Q2,Q2的重新投递延迟为10s,在10s过后再次投递该消息。以此类推,重试越多次重新投递的时间就越久,为此需要设置一个上限,超过投递次数就入死信队列。重试队列与延迟队列有相同的地方,都是需要设置延迟级别,它们彼此的区别是:延迟队列动作由内部触发,重试队列动作由外部消费端触发;延迟队列作用一次,而重试队列的作用范围会向后传递。

05.消费模式之推模式push

对于kafka而言,由Broker主动推送消息至消费端,实时性较好,不过需要一定的流制机制来确保服务端推送过来的消息不会压垮消费端。

06.消费模式之拉模式pull

对于kafka而言,消费端主动向Broker端请求拉取(一般是定时或者定量)消息,实时性较推模式差,但是可以根据自身的处理能力而控制拉取的消息量。

07.消息回溯

一般消息在消费完成之后就被处理了,之后再也不能消费到该条消息。消息回溯正好相反,是指消息在消费完成之后,还能消费到之前被消费掉的消息。对于消息而言,经常面临的问题是“消息丢失”,至于是真正由于消息中间件的缺陷丢失还是由于使用方的误用而丢失一般很难追查,如果消息中间件本身具备消息回溯功能的话,可以通过回溯消费复现“丢失的”消息进而查出问题的源头之所在。消息回溯的作用远不止与此,比如还有索引恢复、本地缓存重建,有些业务补偿方案也可以采用回溯的方式来实现。

08.消息堆积

流量削峰是消息中间件的一个非常重要的功能,而这个功能其实得益于其消息堆积能力。从某种意义上来讲,如果一个消息中间件不具备消息堆积的能力,那么就不能把它看做是一个合格的消息中间件。消息堆积分内存式堆积和磁盘式堆积。

09.消息追踪/轨迹

对于分布式架构系统中的链路追踪(trace)而言,大家一定不会陌生。对于消息中间件而言,消息的链路追踪(以下简称消息追踪)同样重要。对于消息追踪最通俗的理解就是要知道消息从哪来,存在哪里以及发往哪里去。基于此功能下,我们可以对发送或者消费完的消息进行链路追踪服务,进而可以进行问题的快速定位与排查。想要知道消息发送成功了吗?发送的消息在消费端为什么消费不到?为什么又会重复消费?等等问题。引入消息轨迹可以知道消息从生产者触发,经由broker等代理存储,再到消费者消费的整个过程,各个节点的状态、时间、地点等数据汇聚而成完整的链路信息。

10.消息过滤

消息过滤是指按照既定的过滤规则为下游用户提供指定类别的消息。就以kafka而言,完全可以将不同类别的消息发送至不同的topic中,由此可以实现某种意义的消息过滤,或者Kafka还可以根据分区对同一个topic中的消息进行分类。不过更加严格意义上的消息过滤应该是对既定的消息采取一定的方式按照一定的过滤规则进行过滤。同样以Kafka为例,可以通过客户端提供的ConsumerInterceptor接口或者Kafka Stream的filter功能进行消息过滤。对于rocketmq来说,支持Tag、SQL92和类过滤器(新版去除)等3种模式。

11.消息审计

消息审计是指在消息在生产、存储和消费的整个过程之间对消息个数及延迟的审计,以此来检测是否有数据丢失、是否有数据重复、端到端的延迟又是多少等。有关产品:Uber的Chaperone、LinkedIn的kafka monitor、Confluent Control Center等,有需要或感兴趣可自行通过网络了解下。

12.消息路由

将消息路由到指定的队列中,消费者消费队列里的消息。RabbitMQ可以从交换器Exchanger根据路由键路由到指定一个或多个队列。kafka默认是按照消息主题进行路由,消息路由在kafka中使用场景较少,使用起来也比较麻烦,如无特殊需要,一般不推荐使用。

参考资料

《深入理解Kafka》

http://www.likecs.com/default/index/show?id=14248

 

责任编辑:武晓燕 来源: 搬运工来架构
相关推荐

2023-04-27 07:43:22

RabbitMQ重试队列死信队列

2019-08-23 12:12:49

MQ消息队列

2023-07-26 08:21:33

2020-06-22 18:54:39

消息队列幂等性

2021-05-31 08:00:00

消息队列架构Rabbit MQ

2023-10-10 13:39:53

Spring队列优化

2024-04-15 00:00:00

RabbitMQ死信队列消息

2017-10-11 15:08:28

消息队列常见

2023-11-03 10:33:26

2019-10-22 08:12:49

消息队列分布式系统

2024-03-18 00:00:03

RabbitMQ代码延迟队列

2023-03-10 07:22:40

2021-04-12 06:00:01

MongoDB数据库存储

2016-03-28 13:39:58

戴尔

2023-11-30 07:43:14

消息队列架构

2023-09-13 08:14:57

RocketMQ次数机制

2011-06-14 10:57:31

SQL Server管理

2022-11-11 17:09:55

微服务RPC

2021-08-05 15:04:14

消息队列后端

2016-03-28 13:45:14

硬盘
点赞
收藏

51CTO技术栈公众号