典型的应用场景
1 跨系统的异步信息通信
2 应用内的同步变成异步
秒杀场景,把对controller请求放到消息请求队列中
3 基于Pub/Sub模型实现的事件驱动
4 利用RabbitMq实现事务的最终一致性
基本介绍
AMQP协议,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品、不同开发语言的限制
特性
1 可靠性
2 灵活的路由
3 消息集群
4 高可用
5 多种协议
6 多语言客户端
7 管理界面
8 插件机制
工作模型
Exchange交换机 没有自己的进程,只是一个地址列表判断需要发到哪一个队列。队列是用来存储消息。交换机和队列会设置一个绑定关系,定义一个绑定关键字(binding key),发送消息的时候消息会携带一个路由关键字(routing key),当路由关键字和绑定关键字所匹配的时候,我们发送的消息就会从交换机到达队列上面。
Exchange交换机
直连交换机(Direct Exchange)
举例 :
basicPublish("DIRECT_EXCHANGE","key1","hello RabbitMQ") ;
直连类型的交换机跟队列绑定时,必须指定一个明确的绑定关键字,发送消息的时候只有一个绑定关系匹配到
主题交换机(Topic Exchange)
主题类型的交换机跟队列绑定时,必须指定一个明确的绑定关键字,但是可以使用通配符
* 代表一个单词
# 代表零个或多个单词
basicPublish("DIRECT_EXCHANGE","sh.abc","hello RabbitMQ") ; 会指定到 队列1
basicPublish("DIRECT_EXCHANGE","bj.abc.def","hello RabbitMQ") ; 会指定到 队列2
basicPublish("DIRECT_EXCHANGE","sh.food","hello RabbitMQ") ; 既满足队列1 又满足队列4 会同时到达队列1和队列4
广播交换机(Fanout Exchange)
广播类型交换机队列绑定到广播类型的交换机的时候不需要指定任何类型的绑定关键字,我们发送消息的时候也不需要携带任何的路由关键字,也就是说只要发送了消息,广播交换机会给所有队列发送消息。
几个常见的问题
1 怎么自动删除没人消费的消息?
TTL(time to live) 设置一个队列的消的TTL 队列的消息到了指定的时间都会被删除
指定消息的TTL,在发送消息的时候单独为消息指定存活时间。
2 无法路由的消息,去了哪里?
死信队列(Dead Letter Queue) DXL(Dead Letter Exchange) 死信交换机
1消息过期 2发送消息,消费端启用手动应答并且拒绝了消息 3队列达到最大长度,先入队的消息会变成死信。
3 可以让消息优先得到消费吗?
优先级队列 设置队列的最大优先级,在发送消息的时候设置消息的优先级。优先级高的消息会被优先投递
4 如何实现延迟发送消息
延迟队列 1延迟队列的插件 2 先设置一个消息的存活时间,原本消息队列的消息会成为死性队列到达死性交换机,死性交换机绑定了一个队列,就可以实现延迟发送消息。(TTL和DXL配合实现延迟发送消息)
5 RabbitMQ流量控制怎么做?设置队列大小有用吗?
发送200个请求 x-max-length = 80 1 消息堆积的时候有用 2 先进入队列的120条消息删除了 所以设置队列大小不能限流
1 服务端 Flow Control(对硬件内存的可用率做控制) ram disc(从可用磁盘进行控制)
2 消费端 prefetch count(预取数量) channel.basicQos(2) 消费者2 只处理两个消息 剩余的198个请求都由消费者1处理