RabbitMQ
2024-01-28 10:08:50 12 举报
AI智能生成
登录查看完整内容
RabbitMQ是一个开源的消息代理和队列服务器,用于通过轻量级的消息协议在分布式系统中存储和转发消息。它基于AMQP(高级消息队列协议)标准,支持多种编程语言和平台。RabbitMQ提供了可靠的消息传递机制,确保消息不会丢失或重复,并且可以在多个消费者之间进行负载均衡。它还提供了消息确认机制,确保消费者成功处理了消息后才会被删除。RabbitMQ具有高可用性和可扩展性,可以轻松地部署在云环境中或与其他系统集成。它被广泛应用于微服务架构、异步处理、事件驱动架构等场景中,以提高系统的可靠性和性能。
作者其他创作
大纲/内容
消息吞吐量在1w~10w级
没有消费者组的概念,需要依赖Exchange和队列之间的绑定关系
概述
模型设计图
保证可靠性。RabbitMQ使用一些机制来保证可靠性。如持久化、传输确认、发布确认等
具有灵活的路由功能。在消息进入队列之前,是通过Exchange(交换器)来路由消息的。对于典型的路由功能,针对更复杂的路由功能,可以将多个Exchange绑定在一起,也可以通过插件机制来实现自己的Exchange
支持多语言客户端.RabbitMQ几乎支持所有常用的语言,比如Java、.NET、Ruby等
提供管理界面.RabbitMQ提供了一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面
提供跟踪机制.RabbitMQ提供了消息跟踪机制。如果消息异常,使用者可以查出发生了什么情况
提供插件机制.RabbitMQ提供了许多插件,从多方面进行扩展,也可以编写自己的插件
特点
VirtualHost(虚拟主机)
客户端与RabbitMQ进行交互,首先就需要建立一个TCP连接
Connection(连接)
Channel(信道)
这是RabbitMQ中进行数据路由的重要组件。消息发送到RabbitMQ中后,会首先进入一个交换机然后由交换机负责将数据转发到不同的队列中。RabbitMQ中有多种不同类型的交换机来支持不同的路由策略Exchange可以持久化
如果消息中的路由键(RoutingKey)和Binding中的绑定键(binding key)一致,交换器就将消息发送到对应的队列中。路由键与队列名称要完全匹配,如果将一个队列绑定到交换机要求路由键(RoutingKey)为dog,则只转发RoutingKey标记为dog的消息,不会转发dog.puppy消息,也不会转发dog.guard消息等Direct交换器是完全匹配、单播的模式
Direct
Fanout交换器不处理路由键,只是简单地将队列绑定到交换器,发送到交换器地每条消息都会被转发到与该交换器绑定的所有队列中,这很像子网广播,子网内的每个主机都获得了一份赋值的消息
Fanout
Topic交换器通过模式匹配分配消息的路由键属性,将路由键和某种模式进行匹配。此时队列需要绑定一种模式,Topic交换器将路由键和绑定键的字符串切分成单词,这些单词可以用\".\"隔开该交换器会识别两个通配符\"#\"和\"*\",其中\"#\"匹配0个或者多个单词\"*\"匹配不多不少一个单词
Topic
Headers
交换器类型
Exchange(交换机)
用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则可以将交换器理解成一个由绑定构成的路由表
Bingding(绑定)
核心组件
无序消息,效率最高
普通消息
利用队列的FIFO属性,保证一个Exchange只能路由到一个队列上,可以实现顺序消费,但是性能不会很高
顺序消息
延时消息
第一种,消息无法消费成功
第二种,消息已经过期
死信队列
支持的消息类型
不需要确认,效率最高,也最容易丢消息
单向发送
Producer每发送一条信息,等待收到确认之后再发送下一条,消息最可靠,性能不高
单条消息确认
当批量消息中有一条消息出错时,整批消息都需要重传,将会增大重复消费的可能
批量消息确认
同步确认
通过回调接口来判断哪些消息被确认收到,消息最高,实现最复杂
异步确认
消息确认机制
Producer生产消息
由Consumer主动向RabbitMQ拉取消息,请求由consumer发起,broker的压力相对来说会比较小
1.如果只想从队列中获取单挑消息而不是持续订阅,则可以使用channel.basicGet方法来进行消费消息
2.拉模式在消费者需要时采取消息中间件拉取消息,这段网络开销会明显增加消息延迟,降低系统吞吐量
3.由于拉模式需要消费者手动去RabbitMQ中拉取消息,所以实时性较差,消费者难以获取实时消息具体什么时候能拿到新消息完全取决于消费者什么时候去拉取消息
Pull拉取消息
由RabbitMQ Server主动向Consumer推送消息,请求由broker发起,broker压力会比较大
2.推模式将消息提前推送给消费者,消费者必须设置一个缓冲区缓存这些消息,优点是消费者总是有一堆在内存中待处理地消息,所以当真正去消费消息时效率很高,缺点就是缓冲区可能会移除
3.由于推模式时消息到达RabbitMQ后,就会立即被投递给匹配地消费者,所以实施性非常好,消费者能即时得到最新的消息
Push推送消息
消费者接收到消息时,自动地向broker进行提交,容易造成消息丢失
自动提交
由消费者手动在合适的场景下进行提交,更灵活,不容易造成消息没有消费到而丢失
手动提交
当消费者处理消息失败或者当前不能处理该消息时,可以给Broker发送一个拒绝消息的指令.并且可要求Broker将该消息丢弃或者重新放入队列中需要注意的是,当队列中只有一个消费者时,需要确认不会因为拒绝消息并选择重新放入队列中而导致消息在同一个消费者上发生死循环
拒绝一条消息/拒绝多条消息
拒绝消息
消费消息确认机制
在实际场景中,如果对每条消息的处理时间不同,可能导致有些消费者一直很忙,而有些消费者处理很快并一直空间,这时可以通过设置预取数量(PrefetchCount)限制每个消费者在收到下一个确认回直前一次最多可以接收到多少条消息
消息预取
流控机制
Consumer消费消息
单队列+单消息。RabbitMQ当中,针对消息顺序的设计是比较弱的。唯一比较好的策略就是单队列+单消息推送。即一组有序消息,只发到一个队列中,利用队列的FIFO特性保证消息在队列内顺序不会乱.但是这是以极度消耗性能作为代价的。在业务场景中,应该尽量避免这种场景。然后在消费者进行消费时,保证只有一个消费者。同时指定prefetch属性为1
如何保证顺序消费
无法做到绝对的消息不重复
如果采用同步发送确认机制。生产者发送消息之后,要确保一条消息已经发送Broker
如果采用的是异步发送确认机制。需要保证每个消息具有唯一的id,可以供Producer查询到这条消息是否发送到了Broker
尽量不要采用批量消息发送,如果其中某一条消息存在问题,则会导致整批消息都需要重传
消息去重,增加唯一id
给消息增加过期时间,如果在消息存活期内没有被消费,则进入死信队列
问题:有可能Broker已经收到了消息,由于网络抖动,网络向Producer返回的确认ACK,Producer暂未收到,Producer先于Broker重发了消息
Producer
尽可能地做到幂等消费
逐条消费消息,手动确认
首先要确保消息是可以正常被消费的,不然会进入重试队列,一直被消费,直到进入死信队列中
给消息增加一个唯一标识,消费消息时,在业务当中判断一下改消息是否被消费过
问题:Consumer已经消费完了消息,但是在手动提交位点时,发生了宕机,这时Broker将消息转发到了其他的Consumer上,造成了消息的重复消费
Consumer
队列设置为持久化,避免消费过的消息位点没有持久化到磁盘上而重复消费
Broker
如何避免重复消费
消息确认模式调整为同步模式
消费消息时逐条消息消费,并且在业务执行完毕时进行手动提交
将队列声明为持久化
主从集群,每条消息等待其他所有的slave节点复制完成,可以等到大多数节点
调整Broker刷盘的缓冲区大小,缩小刷盘间隔,争取让更多的消息落在磁盘上,防止内存中的数据丢失
尽可能地进行同步刷盘,来一条消息,刷到磁盘上
刷盘分为同步刷盘和异步刷盘
操作系统
如何避免消息丢失
如果业务允许生产速度降低,则可以进行使用,大多数场景下,不会降低生产者生产消息的速度
消息确认机制,尽可能地使用批量消息确认或者异步确认,增大吞吐量,让消费者做到幂等
增加消费者数量,可以提升消息消费的速度
1.增加单台消费者拉取消息的数量,尽可能地一次性拉取多条消息2.增加单台消费者地线程数,并发消费
单条消息调整为手动批量提交,相比逐条消息提交性能会比较好
可以使用懒加载队列的方式,先存入到磁盘,使用到的时候再加载到内存中要付出一定的磁盘IO性能
消息推送模式由Push模式调整为Poll模式,降低Broker的压力
消息堆积如何解决
常见问题
RabbitMQ
0 条评论
回复 删除
下一页