RabbitMQ特性总结
介绍
RabbitMQ 是一个由 Erlang 语言开发的 AMQP(高级消息队列协议)的开源实现。
RabbitMQ 在发消息者和队列之间, 加入了交换器 (Exchange) .
- Exchange:消息交换机,指定消息按什么规则,路由到哪个队列。
- Queue:消息队列,每个消息都会被投入到一个或者多个队列里。
- Routing Key:路由关键字,exchange根据这个关键字进行消息投递。(消息传递时需要一个“RouteKey”,可以简单的理解为要发送到的队列名字。)
- Binding:绑定,它的作用是把exchange和queue按照路由规则binding起来。绑定,用于消息队列和交换器之间的关联。
- Producer:消息生产者,就是投递消息的程序。
- Consumer:消息消费者,就是接受消息的程序。
死信
- 消息被拒绝(basic.reject或basic.nack)并且requeue=false.
- 消息生存时间过期
- 队列达到最大长度(队列满了,无法再添加数据到mq中)
交换机都有哪几种类型
Direct exchange
将队列绑定到交换机,消息的 routeKey 需要与队列绑定的 routeKey 相同。
Fanout exchange
一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上,类似发布订阅。
Topic exchange
把消息路由到bindingKey与routingKey模糊匹配的Queue中,这种交换机是使用通配符去匹配,路由到对应的队列。通配符有两种:"*" 、 "#"。需要注意的是通配符前面必须要加上"."符号。
* 符号:有且只匹配一个词。比如 a.*可以匹配到"a.b"、"a.c",但是匹配不了"a.b.c"。
# 符号:匹配一个或多个词。比如"rabbit.#"既可以匹配到"rabbit.a.b"、"rabbit.a",也可以匹配到"rabbit.a.b.c"。
Headers Exchange
它跟上面三种有点区别,它的路由不是用routingKey进行路由匹配,而是在匹配请求头中所带的键值进行路由。
什么是JMS
JMS(Java Message Service java消息服务)
是一组Java应用程序接口,提供消息的创建,发送,读取等一系列服务。类似于数据库的统一访问接口jdbc.
支持两种发送接收模型:
p2p点对点模型
Pub/sub模型,发布-订阅模型
保证消息可靠性
- 消息持久化
- confirm机制
- 是否顺利到达exchange,成功回调confirm()方法
- Exchange能正确路由到queue,否则回调returnedMessage()
- ACK事务机制
- 是否正确消费消息,是否签收。
几种消息队列实现方案的优缺点对比
消息分发的策略有哪些
分发消息策略有:简单模式、工作队列模式、发布订阅模式、路由模式、通配符模式。
简单模式
只有一个生产者、一个消费者和一个队列。生产者和消费者在发送和接收消息时,只需要指定队列名,而不需要指定发送到哪个Exchange,RabbitMQ服务器会自动使用Virtual host的默认的Exchange,默认Exchange的type为direct。
工作模式
在simple模式下增加消费者的模式,称为work模式。可以有多个消费者,但一条消息只能被一个消费者获取。发送到队列中的消息,由服务器平均分配给不同消费者进行消费。
- 轮询分发 round robin
- 一个生产者两个消费者,消费者1 跟消费者2 处理的数据量完全一样的个数:消费者1:处理偶数消费者2:处理奇数这种方式叫轮询分发(round-robin)结果就是不管两个消费者谁忙,数据总是你一个我一个此时 autoAck = true。
- 公平分发 fair dipatch
- 如果要实现公平分发,要让消费者消费完毕一条数据后就告知MQ,再让MQ发数据即可。要关闭自动应答。
发布订阅模式
生产者发送消息时,不需要指定具体的队列名,Exchange会将收到的消息转发到所绑定的队列。
消息被Exchange转到多个队列,一条消息可以被多个消费者获取。
路由模式
路由模式下Exchange的type为direct。消息的目标队列可以由生产者按照routingKey规则指定。消费者通过BindingKey绑定自己所关心的队列。一条消息队可以被多个消息者获取。只有RoutingKey与BidingKey相匹配的队列才会收到消息。
Topics 通配符模式
消息幂等性保证
- 乐观锁解决
- 通过Redis原子性解决生产者在发送消息时,为每条消息设置一个全局唯一的messageId,消费者拿到消息后,使用setnx命令,将messageId作为key放到redis中。
- 唯一ID+指纹码唯一ID+指纹码机制,利用数据库主键去重Select count(1) from T_order where ID=唯一ID+指纹码
应用场景
延迟队列
下单后30分钟未支付,取消订单,回滚库存。
新用户注册7天后,发送问候短信。
使用场景
异步处理
发送者将消息发送给消息队列之后,不需要同步等待消息接收者处理完毕,而是立即返回进行其它操作。消息接收者从消息队列中订阅消息之后异步处理。
流量削锋
在高并发的场景下,如果短时间有大量的请求到达会压垮服务器。可以将请求发送到消息队列中,服务器按照其处理能力从消息队列中订阅消息进行处理。
应用解耦
通过使用消息队列,一个模块只需要向消息队列中发送消息,其它模块可以选择性地从消息队列中订阅消息从而完成调用。