当前位置: 首页 > 科技观察

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

时间:2023-03-19 15:53:42 科技观察

这些MQ概念你懂吗:死信队列、重试队列、消息回溯等。转载本文请联系搬运工结构公众号。消息队列(MQ)的基本概念在很多情况下都需要弄清楚,这样学习消息队列中间件才能游刃有余。下面分别介绍一下:优先级队列、延迟队列、死信队列、重试队列、消息回溯、消息堆积、消息跟踪/消息跟踪、消息过滤、消息审计、消息路由等01.优先级队列优先级队列是不同的从一个先进先出队列。高优先级的消息有优先被消费的特权,可以为下游不同的消息级别提供保障。但是这个优先级也需要一个前提:如果消费者的消费速度大于生产者的速度,并且消息中间件服务器(一般简称为Broker)中没有消息堆积,那么设置发送消息的优先级是没有的实质意义,因为producer刚刚发送了一条消息,被consumer消费了,所以相当于Broker中至多一条消息,优先级对于单条消息是没有意义的。02.延迟排队你在网上购物时,是否遇到过这样的提示:“30分钟内未付款,订单将自动取消”?这是延迟队列的典型应用场景。延迟队列存储相应的延迟消息。所谓“延时消息”,是指消息发出后,消费者并不想马上拿到消息,而是等待特定的时间,消费者才能拿到消息进行消费。延迟队列一般分为两种:基于消息的延迟和基于队列的延迟。基于消息的延迟是指为每条消息设置不同的延迟时间,那么每当有新的消息进入队列时,就会根据延迟时间重新排序,当然这对性能也会有很大的影响。在实际应用中,多采用基于队列的延迟,设置不同延迟级别的队列,如5s、10s、30s、1min、5mins、10mins等,每个队列中消息的延迟时间相同,即免去了延迟排序需要忍受的性能痛苦,可以通过一定的扫描策略(比如定时)传递超时消息。03.死信队列由于某些原因导致消息无法正确投递。为了保证消息不会被无故丢弃,一般会放在一个特殊角色的队列中,一般称为死信队列。与此对应的还有“回滚队列”的概念。试想一下,如果消费者在消费的时候出现了异常,那么这次的消费就不会被确认(Ack),在回滚消息的操作之后,一直会返回消息。会被放在队列的顶部,然后不断的处理和回滚,导致队列陷入死循环。为了解决这个问题,可以为每个队列设置一个回滚队列,它和死信队列是异常处理的一种机制保障。在实践中,回滚队列的作用可以由死信队列和重试队列来扮演。04.重试队列重试队列其实可以看成是一个回滚队列。具体来说,当consumer消费消息失败时,会再次将消息回滚给Broker,防止消息无故丢失。与回滚队列不同的是,重试队列一般分为多个重试级别,每个重试级别一般也会设置一个重传延迟。重试次数越多,交付延迟就越大。例如:如果消息第一次消费失败,则进入重试队列Q1,Q1的重传延迟为5s,5s后重传消息;如果消息再次消费失败,则进入重试队列Q2,Q2的重投延迟为10s,10s后再次投递消息。以此类推,重试次数越多,重投时间就会越长。为此需要设置一个上限,超过重试次数就会进入死信队列。重试队列和延迟队列有相同的地方,都需要设置延迟级别。它们的区别在于:延迟队列动作是内部触发的,重试队列动作是外部消费者触发的;延迟队列作用一次,重试队列的作用域向后传递。05.消费模式push的推送方式对于Kafka来说,broker主动将消息推送到consumer端,具有更好的实时性,但是需要一定的streaming机制来保证server端推送的消息会不压倒消费者端。06.消费模式的pullmode拉动。对于Kafka,Consumer端主动向Broker端请求拉取(通常是定时或定量的)消息。实时性比push方式差,但是可以根据自己的处理能力来控制。消息量。07.消息回溯一般是消费完成后才处理消息,之后就不能再消费了。消息回溯恰恰相反,就是消息被消费后,之前消费的消息仍然可以被消费。对于消息,我们经常面临的问题就是“消息丢失”。至于是真的因为消息中间件的缺陷还是用户误操作而丢失,一般很难追查。如果消息中间件本身有消息回溯功能,通过回溯消费找回“丢失”的消息,就可以找到问题的根源。消息回溯的作用远不止于此,比如索引恢复,本地缓存重建,一些业务补偿方案也可以通过回溯来实现。08.消息积累流量调峰是消息中间件的一个非常重要的功能,而这个功能其实得益于它的消息积累能力。从某种意义上说,如果一个消息中间件不具备积累消息的能力,就不能算是一个合格的消息中间件。消息堆积分为内存堆积和磁盘堆积。09.消息跟踪/轨迹对于分布式架构系统中的链接跟踪(trace)你一定很熟悉。对于消息中间件,消息链接跟踪(以下简称消息跟踪)同样重要。对消息跟踪最通俗的理解就是知道消息从哪里来,存在哪里,发往哪里。基于此功能,我们可以为发送或消费的消息提供链接跟踪服务,进而快速定位和排查问题。想知道消息是否发送成功?为什么发送的消息在消费端消费不了?为什么会重复消费?等等。消息轨迹的引入,让我们知道了消息从生产者被触发,到代理(如broker)存储,再到消费者消费的全过程。将各个节点的状态、时间、位置等数据聚合起来,形成完整的链路信息。10.消息过滤消息过滤是指按照既定的过滤规则向下游用户提供指定类别的消息。就Kafka而言,完全可以将不同类别的消息发送到不同的topic,从而达到一定意义上的消息过滤,或者Kafka也可以根据partitions对同一topic中的消息进行分类。但是,更严格意义上的消息过滤应该是按照一定的过滤规则,以一定的方式对给定的消息进行过滤。同样以Kafka为例,可以通过客户端提供的ConsumerInterceptor接口或者KafkaStream的filter函数来进行消息过滤。对于rocketmq,支持Tag、SQL92、classfilter(新版本移除)3种模式。11.消息审计消息审计是指在消息的生产、存储、消费全过程中对消息的数量和时延进行审计,以检测是否存在数据丢失、数据是否重复、是否端到端等。到结束延迟是等待多少。相关产品:Uber的Chaperone,LinkedIn的kafkamonitor,ConfluentControlCenter等,如果有需要或者有兴趣可以通过网络了解一下。12、消息路由将消息路由到指定队列,消费者在队列中消费消息。RabbitMQ可以根据路由键从Exchanger路由到指定的一个或多个队列。Kafka默认根据消息主题进行路由。Kafka中很少使用消息路由,使用起来比较麻烦。如果没有特殊需要,一般不推荐。参考《深入理解Kafka》http://www.likecs.com/default/index/show?id=14248