RabbitMQ是由 Erlang 语言编写的,基于 AMPQ 协议的开源消息中间件,使用信道的方式传输数据,信道是建立在真实TCP连接内的虚拟连接,且每条TCP连接上的信道数量没有限制
exchange:交换机,内部实现为保存 binding routing_key和queue关系的查找表
queue:队列,具有自己的erlang进程
routing_key:路由key,用于和queue的绑定关系
channel:通道,实际进行路由工作的实体,即按照 routing_key 将 message 投递给对应的 queue
vhost:工作空间,用于分隔不同应用间的消息,内部均含有独立的 queue、exchange 和 binding 等
1)、服务间异步调用(RPC),即服务解耦
2)、最终一致性的分布式事务
3)、请求削峰,减少DB压力
4)、消息顺序消费
优点:服务间高度解耦、服务异步处理提高性能、流量削峰填谷
缺点:系统复杂性高(消息丢失、重复消费、消费顺序等)、系统可用性降低(MQ挂可能导致应用不可用)、服务之间的数据一致性问题
1)、direct(默认方式,处理路由key,即exchange和queue都需要绑定key),一对一的方式
2)、fanout(不处理路由key,即exchange和queue都不需要绑定key),一对多的广播方式
3)、topic(匹配处理路由key,即exchange和queue都需要绑定key) ,一对多的广播方式
# 匹配一个或者多个
. 匹配一个
1、消息轮询分发(round-robin)(默认)
2、公平分发( provider 和 consumer 都设置 basicQos 的值,consumer 的自动确认修改为手动确认)
1)、APMQ 事务机制 txSelect txCommit txRollback,请求太多性能降低,即吞吐量低
2)、confirm 模式,异步模式,消息发送之后MQ将消息持久化之后发送回执给 provider
1)、增加消费者的处理能力(优化代码或者增加消费者)
2)、设置并发消费,rabbitMQ 默认消费者是单线程串行消费,设置 concurrentConsumers 和 prefetchCount,concurrentConsumers 是对每个 listener 在初始化的时候设置的并发消费者个数,prefetchCount 是每次一次性从 broker 里面取得待消费的消息个数
3)、建立新的queue,消费者同时订阅新旧 queue
4)、生产者端先缓存数据,在mq被消费到一定数量时再发送到mq中
5)、写一个临时处理堆积消息的consumer程序,先直接将消费积压的mq消息均匀的轮询到临时建立的一定数量的queue中,接着使用一定数量的consumer来消费临时queue中的消息
1)、消息持久化:Exchange 设置持久化:durable:true;Queue 设置持久化;Message 持久化发送
2)、ACK确认机制:消息发送确认和消息消费确认
1)、通过业务唯一ID来避免重复消费,比如通过数据库主键冲突实现
2)、生产消息时产生一个唯一消息ID,通过缓存唯一ID来避免重复消费
1)、消息通过hash后分发到不同队列中,每个队列只对应一个消费者
2)、一个队列就对应一个消费者消费,消费者内部做一个实现排序的内存队列,消费者从内存队列中获取任务执行
一、介绍
当消息在一个队列中变成死信 (dead message) 之后,它能被重新publish到另一个Exchange,这个Exchange就是DLX
二、消息变成死信的场景
1)、消息被拒绝(basic.reject/basic.nack) && requeue = false
2)、消息TTL过期,即消息过期了
3)、队列达到最大长度
三、处理过程
1)、DLX也是一个正常的Exchange,和一般的Exchange没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性
2)、当这个队列中有死信时,RabbitMQ就会自动的将这个消息重新发布到设置的Exchange上去,进而被路由到另一个队列
3)、可以监听这个队列中的消息做相应的处理
创建的queue,无论是元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息同步到多个实例的queue里
优点:保证了MQ高可用性(HA),消息不丢失
缺点:一是同步数据时性能开销大(网络带宽压力大),二是扩展MQ时,新机器需要同步所有queue的所有数据,性能开销大
集群架构如下: