MQMessgae Queue)
什么是MQ
MQ全称为Message Queue,即消息队列,消息队列是应用程序与应用程序之间通信的一致方法,即在消息的传输过程中保存消息的容器,多用于分布式系统之间的通信
分布式系统通信的两种方式
直接远程调用
借助第三方完成间接通信
MQ的优势
应用解耦
异步提速
削峰填谷
应用解耦
MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合。
未使用MQ之前
如下图有一个订单系统直接调用库存系统,支付系统,物流系统
由于订单系统与库存系统是耦合的,如果库存系统出现了错误,可能也会影响订单系统不能工作
如果要新接入一个系统我们还要改变订单系统的源码,并添加一系列代码来实现调用
这就暴露了一个巨大的缺点,系统的耦合性越高,容错性就越低,可维护性就越低
使用MQ之后
订单系统只要将对应的数据发送到MQ即可,而库存系统,支付系统,物流系统只需MQ中取出对应的数据即可
如果库存系统出现了错误,也不会影响到订单系统,比如库存系统由于访问量过大突然卡了几秒钟,几秒钟之后可能就好了,好了之后再到MQ中取出对应的数据即可
比如我们要接入一个系统,我们不需要再修改订单系统的源码,直接让该系统去MQ中取出对应的数据即可
小总结:
使用MQ使得应用之间实现了解耦,提升容错性与可维护性
异步提速
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
未使用MQ
有一个订单系统如图
用户下订单一共需要300+300+300+20=920ms,订单系统需要一一调用数据库,库存,支付,物流系统,耗时极大
使用MQ之后
用户下订单需要20+5=25ms
用户下单后,订单系统只需要进行数据库查询和将数据发送到MQ即可告诉用户下单成功,剩下的只需让库存,支付,物流系统自行去MQ中取出数据即可
小总结
提升了用户体验与系统吞吐量
削峰填谷
未使用MQ前
但是当请求忽然增加大于了A系统能处理的最大请求数之后就会导致A系统崩溃
使用MQ之后
如订单系统,在下单的时候就会往数据库写数据。但是数据库只能支撑每秒1000左右的并发写入,并发量再高就容易宕机。低峰期的时候并发也就100多个,但是在高峰期时候,并发量会突然激增到5000以上,这个时候数据库肯定卡死了。
消息被MQ保存起来了,然后系统就可以按照自己的消费能力来消费,比如每秒1000个数据,这样慢慢写入数据库,这样就不会卡死数据库了。
但是使用了MQ之后,限制消费消息的速度为1000,但是这样一来,高峰期产生的数据势必会被积压在MQ中,高峰就被“削”掉了。但是因为消息积压,在高峰期过后的一段时间内,消费消息的速度还是会维持在1000QPS,直到消费完积压的消息,这就叫做“填谷”
小结
应用解耦:提高系统容错性与可维护性
异步提速:提升用户体验和系统吞吐量
削峰填谷:提高系统稳定性
MQ的劣势
系统可用性降低
系统的复杂性度提高
一致性问题
系统可用性降低
系统引入的外部依赖越多,稳定性越差,一旦MQ挂机,就会对业务造成影响,需要保证MQ的高可用
系统的复杂性度提高
MQ的加入大大增加了系统的复杂度,以前系统之间是同步的远程调用,现在是通过MQ的异步调用,如何保证消息没有重复消费?如何处理消息丢失的情况?如何保证消息的一致性问题
一致性问题
A系统处理完业务,通过MQ给B,C,D三个系统发消息数据,如果B系统,C系统处理成功,D系统处理失败。如何保证数据处理的一致性
什么时候使用MQ
1.生产者不需要从消费者处获得反馈,引入消息队列之前的调用,其接口返回值因该为空,这才让异步成为了可能
2.容许短暂性的不一致
3.确实是用了可以提升系统稳定性等等,即解耦,提速,削峰这些方面带来的收益,超过了MQ,管理MQ这些成本
常见的MQ产品
目前业界有很多MQ产品,例如RabbitMQ,RocketMQ, ActiveMQ, ZeroMQ, MetaMQ , 也有直接使用Redis充当消息队列的,而这些消息队列产品,在实际选型时,需要结合自身需求与产品特征综合考虑