目录
1.MQ概述
- MQ全程Message Queue (消息队列),是在消息的传输过程中保存消息的容器,多用于分布式系统之间进行通信。
- 分布式系统中的通信方式:直接远程调用 和借助第三方完成间接通信
- 发送方称之为生产者,接收方称之为消费者
2.MQ的基本概念
2.1MQ的优势和劣势
2.1.1优势
- 应用解耦
系统A要发送一个消息到多个系统,如果此时每增加一个系统,系统A都需要通过修改源码来增加接口,此时耦合非常高,但是如果中间使用消息队列的话,系统只需要发送一次到消息队列,别的系统就能复用该信息,当增加或删除系统调用接口的时候,不需要额外的更新代码。
- 异步提速
提升用户体验和系统吞吐量
用户调用一个接口的时候,可能该接口调用了别的方法。例如:用户注册的时候,后台可能需要调用:查询数据库,插入数据库,发送邮件,发送用户指南等等...
但是用户可能并不需要后台将所有的任务执行完毕,那么此时在初入数据口后面加入mq队列,用户就能很快得到注册成功的响应而去做一些别的事情。mq的机制又能保证最终的一致性,所以使用起来很安全很稳定。
- 削峰填谷
提高系统稳定性
何为削峰,就是当系统压力过大的时候,让系统压力减小。如何做?
加入数据库的读写每秒3000,在高峰期,系统的访问达到了每秒10000。此时由于加入了消息队列,所以不会出现激增的访问导致系统奔溃。
消息被MQ保存起来了,然后系统就可以按照自己的消费能力来消费,比如每秒3000个数据,这样慢慢写入数据库,这样就不会卡死数据库了。
在高峰期过后的一段时间内,消费消息的速度还是会维持在3000,直到消费完积压的消息,这就叫做“填谷”
(注意,削峰并不会让用户的等待时间减少,所以一般会跟异步搭配来使用)
2.1.2劣势
- 系统可用性降低,复杂性提高
本来系统之间直接通行调用接口就行了,但是引入了mq导致系统的复杂度大大增加,并且如果mq挂掉了,那么系统之间的通信就中断了,导致整个系统的全部挂掉。
- 一致性问题
A系统处理完了发送到消息对流后直接返回成功了,用户以为你这个请求就成功了;但是问题是,其他系统消费该消息后,如果当中有一个系统出现了问题,导致数据丢失。最后就会发生数据不一致等问题。
3.MQ小结
在软件的正常功能开发中,并不需要去刻意的寻找消息队列的使用场景,而是当出现性能瓶颈时,去查看业务逻辑是否存在可以异步处理的耗时操作,如果存在的话便可以引入消息队列来解决。否则盲目的使用消息队列可能会增加维护和开发的成本却无法得到可观的性能提升,那就得不偿失了。
3.1使用MQ满足的条件
- 不需要同步处理的(a->b 不需要返回值)并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间
- 容许短暂的不一致性,最终也会一致
- 对于使用成本来看确实是有效果,不需要刻意去使用
4.RabbitMQ简介
市场上常见的消息队列有如下:
-
ActiveMQ:基于JMS
-
ZeroMQ:基于C语言开发
-
RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好
-
RocketMQ:基于JMS,阿里巴巴产品
-
Kafka:类似MQ的产品;分布式消息系统,高吞吐量
4.1AMQP
- AMQP 一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。
- AMQP是一个二进制协议,拥有一些现代化特点:多信道、协商式,异步,安全,扩平台,中立,高效。
- RabbitMQ是AMQP协议的Erlang的实现。
RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。
RabbitMQ官方地址:http://www.rabbitmq.com/
RabbitMQ提供了6种模式:简单模式,work模式,Publish/Subscribe发布与订阅模式,Routing路由模式,Topics主题模式,RPC远程调用模式;
官网对应模式介绍:https://www.rabbitmq.com/getstarted.html
5.RabbitMQ安装和配置
https://blog.csdn.net/adminBfl/article/details/110645865
6.RabbitMQ提供6种模式
6.1简单模式
也就是一个生产者对应一个消费者。
6.1.1生产者
6.1.2消费者
6.2work模式:
概述:一个生产者对应多个消费者,但是只能有一个消费者获得消息,也称之为竞争消费者模式。
应用场景:对于 任务过重或任务较多情况使用工作队列可以提高任务处理的速度。
6.2.1生产者
6.2.2消费者1
6.2.2消费者2
6.3发布/订阅模式:
一个消费者将消息首先发送到交换器,交换器绑定多个队列,然后被监听该队列的消费者所接收并消费。
在订阅模型中,多了一个exchange角色,而且过程略有变化:
-
P:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)
-
C:消费者,消息的接受者,会一直等待消息到来。
-
Queue:消息队列,接收消息、缓存消息。
-
Exchange:交换机,图中的X。一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有常见以下3种类型:
-
Fanout:广播,将消息交给所有绑定到交换机的队列
-
Direct:定向,把消息交给符合指定routing key 的队列
-
Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
-
Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失!
6.3.1生产者
6.3.2消费者1
6.3.2消费者2
6.4路由模式:
路由模式特点:
-
队列与交换机的绑定,不能是任意绑定了,而是要指定一个
RoutingKey
(路由key) -
消息的发送方在 向 Exchange发送消息时,也必须指定消息的
RoutingKey
。 -
Exchange不再把消息交给每一个绑定的队列,而是根据消息的
Routing Key
进行判断,只有队列的Routingkey
与消息的Routing key
完全一致,才会接收到消息
6.4.1生产者
6.4.2消费者1
https://gitee.com/bufanli/rabbit-mq/blob/master/simple-consumer/src/main/java/cn/bufanli/consumer/ConsumerRouting1.java
6.4.2消费者2
https://gitee.com/bufanli/rabbit-mq/blob/master/simple-consumer/src/main/java/cn/bufanli/consumer/ConsumerRouting2.java
生产者将消息发送到direct交换器,在绑定队列和交换器的时候有一个路由key,生产者发送的消息会指定一个路由key,那么消息只会发送到相应key相同的对列,接着监听该队列的消费者消费消息。
6.5通配符模式:
图解:
-
红色Queue:绑定的是
usa.#
,因此凡是以usa.
开头的routing key
都会被匹配到 -
黄色Queue:绑定的是
#.news
,因此凡是以.news
结尾的routing key
都会被匹配
Topic
类型与Direct
相比,都是可以根据RoutingKey
把消息路由到不同的队列。只不过Topic
类型Exchange
可以让队列在绑定Routing key
的时候使用通配符!
Routingkey
一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: order.info
6.5.1生产者
6.5.2消费者1
https://gitee.com/bufanli/rabbit-mq/blob/master/simple-consumer/src/main/java/cn/bufanli/consumer/ConsumerTopic1.java
6.5.2消费者2
https://gitee.com/bufanli/rabbit-mq/blob/master/simple-consumer/src/main/java/cn/bufanli/consumer/ConsumerTopic2.java
Topic主题模式可以实现 Publish/Subscribe发布与订阅模式
和 Routing路由模式
的功能;只是Topic在配置routing key 的时候可以使用通配符,显得更加灵活
7.模式总结
RabbitMQ工作模式:
1、简单模式 HelloWorld一个生产者、一个消费者,不需要设置交换机(使用默认的交换机)
2、工作队列模式 Work Queue一个生产者、多个消费者(竞争关系),不需要设置交换机(使用默认的交换机)
3、发布订阅模式 Publish/subscribe需要设置类型为fanout的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列
4、路由模式 Routing需要设置类型为direct的交换机,交换机和队列进行绑定,并且指定routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列
5、通配符模式 Topic需要设置类型为topic的交换机,交换机和队列进行绑定,并且指定通配符方式的routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列