消息队列
MQ(Message Queue),即消息队列,是在消息的传输过程中保持消息的容器。多用于系统之间的异步通信。
同步通讯是建立在双方时刻保持通讯的情况下,即双方是需要保持一个连接状态
异步通讯是建立在由第三方(消息队列)转发的基础上(即代理模式),会导致消息存在延迟;特点是双方不需要时刻保持连接,在上线后即可将消息队列内对应的数据进行转发操作。
队列的特点是先进先出,从一端进行添加操作,在另一端进行删除操作;
消息队列除了数据结构的存储特性之外,还充当一个容器的作用,保存双方需要发送的数据。
RabbitMQ的优点与缺点
订单系统对接MQ,再由MQ来对接库存、支付、物流等系统,而不是由订单系统来直接对接其他系统;
即 客户端→订单系统→MQ→库存、支付、物流等系统
优点
1.解耦合,提高系统之间的容错性和可维护性(即提高系统之间的稳定性)。
2.异步提速,客户端下订单时,只需要访问订单系统,再由订单系统调用MQ即可得到响应;从而减少了调用库存、支付、物流等系统的反应时间来达到提速效果,即提高了用户的体验。
当然在响应完客户端后,还得由MQ来给库存、支付、物流等系统发送消息数据进行进一步的操作;
3.削峰填谷,在处理秒杀活动等高流量场景时,可以使用MQ消息队列进行一个缓冲和限制消费消息的操作;从而来控制流量不至于让服务器崩溃。即用MQ来控制服务器能够承受的消费消息范围。
缺点
1.系统的可用性降低,系统引入的外部依赖越多,系统稳定性越差。
即使用了MQ后,一旦MQ宕机,就会对业务造成影响。
解决方法是搭建MQ集群
2.系统复杂度提高,MQ的加入大大增加了系统的复杂度,原本是系统之间同步的远程调用,现在是通过MQ进行异步调用。提升了维护的难度。
3.一致性问题,例如A系统处理完业务,通过MQ来给B、C发送消息数据,B处理成功,C处理失败,则会造成数据处理的不一致。
解决方法是实现ACID事务一致性。
MQ的应用场景
1.抢红包、秒杀活动、抢火车票等场景
这些业务场景都是短时间内需要处理大量请求,如果直接连接系统处理业务,将会耗费大量资源,甚至造成系统的瘫痪。
而使用MQ,就可以让用户请求先发送到MQ中保存起来,并且MQ会进行消息的排队处理,先请求的秒杀成功,后请求的秒杀失败。
2.消息分发
如电商网站要推送促销信息,业务耗费时间比较多(例如需要给用户在多个系统进行推送),但是对时效性要求不高,此时可以使用MQ做消息分发。
3.数据同步
假如需要将数据保存到数据库之外,还需要一段时间将数据同步到缓存(如redis)、搜索引擎(如Elasticsearch)时,此时可以将数据库的数据作为消息发送到MQ中,再由MQ同步到缓存、搜索引擎中。即由MQ代为同步。
4.异步处理
订单系统处理完后,直接返回订单结果,再通过MQ来通知子系统进行下一步的操作,执行一些非实时的业务操作。这样可以保证核心业务的高效与及时,也就是保证订单系统的高性能。
5.离线处理
在银行系统中,如果要查询近十年的历史账单,这是非常耗时的操作。如果发送同步请求,则需要大量时间等待响应。此时可以发送异步请求到MQ,让MQ转发请求到历史账单系统,等待查询出结果后获取即可。
AMQP
即Advanced Message Queuing protocol(高级消息队列协议),是一个网络协议,专门为消息中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受不同中间件产品、不同开发语言等条件的限制。
AMQP的工作过程
生产者Publisher将消息发布到交换机Exchange,交换机根据规则将消息分发给交换机绑定的队列Queue,队列再把消息发送到订阅此队列的消费者。
AMQP的工作原理
Connection对Producer生产者/Consumer消费者和RabbitMQ服务器之间的TCP连接,
即RabbitMQ通过Connection的信道channel(一条TCP可以创建多条信道)与生产者/消费者进行一个TCP的连接操作。
Virtual host
虚拟主机,每个vhost本质上就是一个mini的RabbitMQ服务器,拥有自己的队列、交换机、绑定和权限机制。当多个不同的用户使用同一个RabbitMQ服务器时,可以划分出多个虚拟主机。默认的虚拟主机路径是/
Exchange交换机的作用是接收生产者的消息,再根据分发规则将消息分发给服务器中的queue。不同的交换机有不同的分发规则。
Queue
消息队列,用来保存消息直到发送给消费者。它是一个消息容器,等待消费者链接到这个队列将其取走。
Binding
消息队列与交换机之间的虚拟连接,绑定中包含路由规则,绑定信息保存到交换机的路由表中,作为消息的分发依据。
RabbitMQ使用信道的原因 :
TCP连接的创建于销毁开销特别大。创建需要3次握手,销毁需要4次分手。会造成资源的浪费,操作系统每秒处理TCP的连接数也是有限制的,会造成性能瓶颈。当一条线程使用一个信道,一条TCP链接可以容纳无限的信道,即使每秒成千上万的请求也不会成为性能的瓶颈。
总结:总体来说就是让MQ代为处理那些耗时的操作,做出基本判断后直接向客户端返回结果,再给MQ交代业务(即相当外包给MQ去处理,自己则可以腾出时间继续处理核心业务),还有可以在高流量的时候进行一个限流操作;既可以提高用户体验,又可以解耦合,提高可维护性。整个工作流程就是生产者通过信道与RabbitMQ服务器进行链接,生产者把消息发送Virtual host中的Exchange,Exchange再根据分发规则(路由表)来分发给服务器中的queue,queue将Exchange发给它的消息保存,等待消费者接收完该消息再出队(删除消息)。