RabbitMQ
1 啥是MQ
- MQ(message queue),按词组解释的意思就是
消息队列
- MQ是在消息的传输过程中保存消息的容器
- 队列遵循
FIFO
也就是先入先出规则(先进来的水先出去) - 它是典型的:生产者、消费者模型
- 消息的生产和消费都是异步的
- MQ是一种跨进程的通讯机制,用于上下游系统传递消息
- RabbitMQ使用AMQP(高级消息队列协议Advanced Message Queuing Protocol)
- MQ是一种对上下游系统“逻辑解偶+物理解偶”的
消息通讯服务
2 为啥用MQ
2.1 流量消峰
在特定的时间瞬间出现的大量请求数据,MQ可以将超出系统承受能力的请求进行排队处理
假设我们有一个应用,平时访问量是每秒300请求,我们用一台服务器即可轻松应对
而在高峰期,访问量瞬间翻了十倍,达到每秒3000次请求,那么单台服务器肯定无法应对,这时我们可以考虑增加到10台服务器来实现访问压力的负载均衡
但如果这种瞬时高峰的情况每天只出现一次,每次只有半小时,那么我们10台服务器在多数时间都只分担每秒几十次请求,这样就有点浪费资源了
这种情况,我们就可以使用MQ来进行流量削峰,高峰情况下,瞬间出现的大量请求数据,先发送到消息队列服务器,排队等待被处理,而我们的应用,可以慢慢的从消息队列接收请求数据进行处理,这样把数据处理时间拉长,以减轻瞬时压力
2.2 应用解偶
MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合,降低了上下游系统的强依赖关系
假如现在有个电商系统,订单模块依赖支付模块而存在,所以,如果支付系统坏了,那么订单系统也就没有意义了;如果有了MQ就不一样了,两个系统不再直连,而是生产者将消息发送到队列上进行排队。消费者去队列里面取,如果支付系统出现了问题,生产者正常向MQ的队列发送消息,MQ将消息存在队列中,直至支付系统恢复正常后再将存在队列里的消息拿出来继续处理。
2.3 异步处理
因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦
3 AMQP和JMS
MQ是消息通信的模型,并发具体实现。现在实现MQ的有两种主流方式:AMQP、JMS
两者间的区别和联系:
AMQP | JMS |
---|---|
通过规定协议来统一数据交互的格式 | 定义了统一的接口,来对消息操作进行统一 |
只是协议,不规定实现方式,因此是跨语言的 | 必须使用Java语言 |
多种消息模型 | 两种消息模型 |
4 用哪个MQ
主流MQ如下,网上对比图有的是,具体差异项就不看了,直接总结:
- ActiveMQ:基于JMS;比较老,且现在不咋更新了,非特殊情况不选用
- RabbitMQ:基于AMQP协议,因为是elang语言的,应用比较深的话学习成本高,但中小型公司完全够用
- RocketMQ:基于JMS,适合技术水平高、有精力向底层研究的团队玩
- kafka:分布式消息系统,高吞吐量,大数据专用
5 RabbitMQ的关键词
未来的学习、使用将一直围绕这些词
- Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输(Broker=Exchange+Queue)
- vhost:每一个vhost本质上是一个mini版的RabbitMQ服务器,拥有自己的交换机、队列、绑定等,拥有自己的权限机制;vhost之于Rabbit就像虚拟机之于物理机一样。他们通过在各个实例间提供逻辑上分离,允许为不同的应用程序安全保密的运行数据
- Producer(生产者):发送消息的应用
- Connection(连接):连接RabbitMQ和应用服务器的TCP连接
- Channel(信道):连接里的一个虚拟通道。当你通过消息队列发送或者接收消息时,这个操作都是通过通道进行的
- Exchange(交换机):消息交换机,接受生产者发送的消息,并根据Binding规则将消息路由给服务器中的队列
- Exchange类似于数据通信网络中的交换机,提供消息路由策略
- producer将消息先发送给Exchange
- Exchange 和Queue的绑定可以是多对多的关系
- producer在传递消息的时候,会传递一个ROUTING_KEY,Exchange会根据这个ROUTING_KEY按照特定的路由算法,将消息路由给指定的queue
- Exchange也可设置为持久化,临时或者自动删除
- Routing Key(路由键):生产者在将消息发送给Exchange的时候,一般会指定一个routing key,来指定这个消息的路由规则。路由键可以说是消息的目的地址
- Binding Key(绑定键):Exchange与Message Queue是通过binding key进行联系的
- Queue(队列):消息的载体,每个消息都会被投到一个或多个队列
- Message(消息):又生产者通过RabbitMQ发送给消费者的信息
- Consumer(消费者):接收消息的应用。
- ACK(消息确认机制):消费者从RabbitMQ收到消息并处理完成后,反馈给RabbitMQ,RabbitMQ收到反馈后才将此消息从队列中删除
- Users(用户):在RabbitMQ里,是可以通过指定的用户名和密码来进行连接的。每个用户可以分配不同的权限,例如读权限,写权限以及在实例里进行配置的权限
6 通讯过程
将上面的关键词联系起来就是下面这样
- 当一个用户要生产/消费消息时,user先建立自己和MQ服务的连接Connection
- 然后开通一个用于传送消息给MQ的通道Channel
- 连接上后,生产者将带有路由键Routing Key的message消息发送给MQ的交换机Exchange
- Exchange根据设置的转发策略类型以及Binding Key绑定自己与队列quene之间的关系后将消息路由给quene
- quene缓存消息,消费者consumer去队列里消费message,消费掉后会回传ACK给quene,quene收到消息对应的ACK后删除这条消息的缓存(可通过配置来决定是持久化还是删除)
7 RabbitMQ的四种交换机
7.1 直连交换机:Direct exchange
- 系统默认的交换机,工作方式类似于单播,Exchange会将消息发送完全匹配ROUTING_KEY的Queue
- 直连交换机是一种带路由功能的交换机,一个队列会和一个交换机绑定,除此之外再绑定一个routing_key
- 当消息被发送的时候,需要指定一个binding_key,这个消息被送达交换机的时候就会被这个交换机送到指定的队列里面去
- 同样的一个binding_key也是支持应用到多个队列中的
- 这样当一个交换机绑定多个队列,就会被送到对应的队列去处理
7.2 扇形交换机:Fanout exchange
广播式交换机,不管消息的ROUTING_KEY是啥,Exchange都会将消息转发给所有绑定的Queue
扇形交换机是最基本的交换机类型,它所能做的事情非常简单———广播消息。
扇形交换机会把能接收到的消息全部发送给绑定在自己身上的队列。
因为广播不需要“思考”,所以扇形交换机处理消息的速度也是所有的交换机类型里面最快的。
7.3 主题交换机:Topic exchange
主题交换器,工作方式类似于组播,Exchange会将消息转发和ROUTING_KEY匹配模式相同的所有队列
-
发送到主题交换机上的消息需要携带指定规则的routing_key
-
主题交换机会根据这个规则将数据发送到对应的(多个)队列上。
-
主题交换机的routing_key需要有一定的规则,交换机和队列的binding_key需要采用
*.#.*.....
的格式,每个部分用.
分开,其中:-
*
表示匹配一个任意词组 -
#
表示匹配0个或多个词组
-
-
当一个队列的绑定键为#的时候,这个队列将会无视消息的路由键,接收所有的消息
7.4 首部交换机:Headers exchange
定义一个Hash的数据结构,消息发送的时候,会携带一组hash数据结构的信息,
当Hash的内容匹配上的时候,消息就会被写入队列
绑定交换机和队列的时候,Hash结构中要求携带一个键“x-match”,这个键的Value可以是any或者all,这代表消息携带的Hash是需要全部匹配(all),还是仅匹配一个键(any)就可以了。相比直连交换机,首部交换机的优势是匹配的规则不被限定为字符串(string)