一,MQ
1,MQ 的概念
MQ 全称 Message Queue(消息队列),是用来存储消息数据的容器(是一个中间件),一般用于分布式系统间的通信;MQ主要介于生产者和消费者之间,生产者将数据发送给消息队列,队列将这些消息数据进行存储,消费者从消息队列中取出消息数据进行消费。
2,分布式系统之间通信的两种方式
2.1 两个通信的系统之间直接进行调用
如下图所示,A和B系统之间的通信方式就是直接进行调用,A需要B的数据的话需要调用相应接口,B给A返回相应数据,B调用A的数据时也是同理;
2.2 借用第三方中间件进行间接调用
大部分分布式系统采用的就是第二种方式使用MQ这样一个消息队列中间件进行间接调用,这里的发送方称为生产者(生产消息),接收方称为消费者(消费消息)!
3,MQ的优势
3.1 应用解耦
假设有这样一个场景,一个用户购买了一件商品,购买商品的时候需要访问订单系统,这个订单系统直接和库存系统、物流系统和支付系统相关联,各个系统之间的关联系统如下:
这个系统的主要业务逻辑是这样的:一个用户在购买商品时,首先访问订单系统,此时订单系统会分别访问库存、物流以及支付系统,只有这三个系统全部响应完成且响应正确的时候订单系统的页面才会正确返回给用户!
假设此时有一个系统响应错误,订单系统就会发生错误或者现在的需要新家一个系统时也不是很方便需要在订单系统中新增有关新系统的业务代码,如果此时介入一个中间件MQ用来存放订单系统给其他系统发送的消息数据时,问题就会迎刃而解;
引入消息队列这样的中间件,作为订单系统就不需要关心其他相关的三个系统的执行了,而且新加入一个系统时也不会直接和订单系统相关,新加入的系统只需要从MQ中拿取消息数据进行消费即可,此时整个系统之间的耦合度就会大大降低!
3.2 异步提速
未加入 MQ 之前的响应速度如图所示:
总的花费时间是存入数据库的5ms+300ms = 305ms
加入 MQ 之后的响应速度如图所示:
总的花费时间是存入数据库的5ms+20ms = 25ms
引入 MQ 之后采用的是异步的方式,订单系统将消息数据发送给MQ之后就直接给用户返回了,而库存、物流以及支付系统分别从 MQ 中拿出消息数据进行消费,这一步站在订单系统的角度是不关心的,三个系统也是并发的去消费消息的,这一过程是异步的,所以 MQ 的另一大优势也体现在异步提速上!
3.3 削峰填谷
假设此时有大量请求,每秒5000访问量访问A系统,但是A系统的处理能力是每秒1000的访问量,此时A系统就会崩溃,未加入 MQ 之前:
加入 MQ 之后:
使用了 MQ 之后,限制消费消息的速度为1000,这样一来,高峰期产生的数据势必会被积压在 MQ 中,高峰就被“削”掉了,但是因为消息积压,在高峰期过后的一段时间内,消费消息的速度还是会维持在1000,直到消费完积压的消息,这就叫做“填谷”。使用MQ后,可以提高系统稳定性。
4,MQ的劣势
1,系统可用性降低
2,系统复杂度提高
3,一致性问题
引入了 MQ 势必会使得系统之间的调用变得更复杂,规则变得更多,对于上述问题 MQ 是怎么解决的后续再详细告知!
二,RabbitMQ
1,RabbitMQ 的概念
2,RabbitMQ 模型架构及相关概念
- Broker:接收和分发消息的应用,RabbitMQ Server就是 Message Broker;
- Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个vhost,每个用户在自己的 vhost 创建 exchange/queue 等;
- Connection:publisher/consumer 和 broker 之间的 TCP 连接;
- Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的 channel 进行通讯,AMQP method 包含了channel id 帮助客户端和 message broker 识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销;
- Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到 queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast);
- Queue:消息最终被送到这里等待 consumer 取走;
- Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据。