87°

RabbitMQ个人笔记

初识RabbtitMQ

此文不涉及RabbitMQ与其他MQ的对比介绍
  • 它是采用Erlang语言实现的AMQP(Advanced Message Queued Protocol)的消息中间件,最初起源于金融系统,用在分布式系统存储转发消息。

  • AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。

  • AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

  • 用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

为什么使用RabbitMQ

  • 当每学到某个技术点是,一到为什么使用的疑问的时候,无非就是讲解他的优点,有什么好处?

  • 这里我们通过一个案例讲解

场景:某个商城系统网站,用户下单创建订单成功后,需要进行邮件发送,短信发送,库存扣减等一系列服务操作  
我们的流程处理是怎样的呢?

传统处理

  • 我们来讲解下以前的传统处理,用户下单创建订单后,由订单服务系统分别调用邮件发送服务,短信发送服务,库存扣减服务等,当请求到达订单系统中了,我们订单系统首先调用其中一个服务进行处理,等待这个服务处理完毕返回后,开始进行另一个服务处理,依此类推.如果一个服务耗时50ms,需要等待处理完毕后才能调用另一个服务,加入有n个服务需要我们去处理,那么这个功能的耗时就是n*50ms,我们把这个过程叫做同步返回处理.

20190508170645106.png

  • 由上图看出,处理这个功能业务时,是同步的,我们耗时也是比较久的,而且多个服务直接都有依赖耦合订单服务系统的,我们开发系统讲究高内聚,低耦合,这很显然不符合,那么我们该怎么优化为异步低耦合的呢?

线程池处理

  • 针对上面的问题,我们看到有同步处理耗时长的问题,然而我们有学过多线程的处理,所以我们可采用线程池的方式

  • 我们在订单服务中加一个线程池这样的一个操作,有线程池产生多个线程去分别调用其他服务,之前一个服务50ms,现在不考虑其他因素,用多线程去处理,就相当于只用了一个服务的调用时间去处理了多个服务的调用,从而我们实现了同步变异步来解决耗时长的问题

20190508170715666.png

  • 问题来了,虽然我们解决了同步变异步的问题,但是我们在订单系统中又多了一个线程池的操作,而且多个服务之间依然是依赖耦合订单服务的,并且用线程池处理的方法应用的比较少,那么我们该如何继续优化呢?

RabbitMQ处理

  • 针对上面的两个处理方式依然不是很理想的,这时候我们使用RabbitMQ来优化这个功能,我们在订单服务处理中加一个消息队列,那么流程就是:用户下单创建订单后,将请求发送到这个消息队列中,我们就无需关注订单服务和其他服务之间的处理,发送消息队列后不管了,直接返回订单信息给用户,由消息队列分发给各个服务进行通讯处理(消息队列如何分发消息后续说明)

20190508170733319.png

  • 解耦

20190508170752760.png

  • 我们从上述图中看出,加一个消息队列的功能时,实现了服务调用的异步实现,既解决了各个服务之间和订单服务依赖耦合的关系,使订单服务单独出来处理,可以把消息队列和各个服务的处理看做一个独立的模块,这样我们解决了最开始的业务场景问题

流量削峰

什么是流量削峰

  • 主要是还是来自于互联网的业务场景,例如,马上即将开始的春节火车票抢购,大量的用户需要同一时间去抢购;

  • 以及大家熟知的阿里双11秒杀,短时间上亿的用户涌入,瞬间流量巨大(高并发),比如:200万人准备在凌晨12:00准备抢购一件商品,但是商品的数量缺是有限的100-500件左右。

  • 这样真实能购买到该件商品的用户也只有几百人左右, 但是从业务上来说,秒杀活动是希望更多的人来参与,也就是抢购之前希望有越来越多的人来看购买商品。

  • 但是,在抢购时间达到后,用户开始真正下单时,秒杀的服务器后端缺不希望同时有几百万人同时发起抢购请求。

  • 我们都知道服务器的处理资源是有限的,所以出现峰值的时候,很容易导致服务器宕机,用户无法访问的情况出现。

  • 这就好比出行的时候存在早高峰和晚高峰的问题,为了解决这个问题,出行就有了错峰限行的解决方案。

  • 同理,在线上的秒杀等业务场景,也需要类似的解决方案,需要平安度过同时抢购带来的流量峰值的问题,这就是流量削峰的由来。

解决方案

  • 我们依然通过一个案例讲解
场景:商城系统新建了一个秒杀活动,在限定时间内进行低价秒杀,可能会出现成千上万的用户前来请求秒杀处理,但是我们的秒杀商品限定了几十或者几百的库存
那么我们如何面对高并发的流量请求来限制流量进行秒杀业务来减少服务器的压力呢?
  • 这时候我们的RabbitMQ的魅力就来啦,我们在系统服务中加入消息队列,把用户所有的请求发送到消息队列中,不直接去交给秒杀的业务处理,虽然有多量的请求,但是我们可以设置消息队列的阈值,当用户请求的数量达到库存的数量时,我们消息队列就可以对其他的请求不进行秒杀下单处理了,可以将其他请求进行秒杀失败的一个业务处理,只负责秒杀成功的请求,然后等待系统的下单处理就行了,从而达到了对高并发流量的限制,保证库存的正确处理,减少服务器的压力

20190508170815513.png

  • 在这里,消息队列就像“水库”一样,拦蓄上游的洪水,削减进入下游河道的洪峰流量,从而达到减免洪水灾害的目的。

简单总结

针对本文的简单介绍,结合所处场景进行一个对RabbitMQ的优点小总结
  • 解耦: 在项目启动之初是很难预测未来会遇到什么困难的,消息中间件在处理过程中插入了一个隐含的,基于数据的接口层,两边都实现这个接口,这样就允许独立的修改或者扩展两边的处理过程,只要两边遵守相同的接口约束即可。

  • 扩展性: 消息中间件解耦了应用的过程,所以提供消息入队和处理的效率是很容易的,只需要增加处理流程就可以了。

  • 削峰: 在访问量剧增的情况下,但是应用仍然需要发挥作用,但是这样的突发流量并不常见。而使用消息中间件采用队列的形式可以减少突发访问压力,不会因为突发的超时负荷要求而崩溃

  • 缓冲: 消息中间件通过一个缓冲层来帮助任务最高效率的执行

  • 异步通信: 通过把把消息发送给消息中间件,消息中间件并不立即处理它,后续在慢慢处理。


全部评论: 0

    我有话说: