消息中间件RabbitMQ(一)RabbitMQ简介

懒驴 2022年02月21日 1,653次浏览

Hello,驴友们好久不见了!

        在企业级应用系统架构演进的过程中,中间件的使用起到了不可磨灭的作用。例如缓存中间件**Redis**,其主要作用在于提高并发读请求情况下查询的性能,减少频繁查询数据库的频率,从而降低DB(数据库)服务器的压力。随着用户流量的快速增长,由于传统应用在系统接口和服务处理模块层面仍然沿用“高耦合” 和“同步”的处理方式,导致接口由于线程阻塞而延长了整体响应时间,即所谓的“**高延迟**”。

        为此,消息中间件RabbitMQ得到了重用。RabbitMQ是目前市面上应用相当广泛的分布式消息中间件,在企业级应用、微服务系统中充当着重要的角色。它可以通过异步通信等方式降低应用系统接口层面的整体响应时间。除此之外,RabbitMQ在一些典型的应用场景和业务处理中具有重要的作用,比如业务服务模块解耦、异步通信、高并发限流、超时业务和数据延迟处理等。
        接下来,我将更新以下内容:

  • 认识RabbitMQ,包括其典型应用场景和作用,并在本地安装RabbitMQ服务。
  • 介绍RabbitMQ相关词汇,包括消息、队列、交换机、路由和各种典型的消息模型。
  • 基于SpringBoot项目为基础整合RabbitMQ,并自定义注入相关Bean配置,采用RabbitMQ相关组件,通过代码实现消息的发生和接收。
  • 基于SpringBoot整合RabbitMQ的项目,实战各种类型的消息模型,并介绍RabbitMQ的几种消息确认消费机制。
  • 采用RabbitMQ实战典型的应用场景,即“用户登录成功的异步写日志”。


RabbitMQ简介

作为市面上位数不多的分布式消息中间件,RabbitMQ的应用相当广泛。
RabbitMQ还是一款开源并实现了高级消息队列协议(即AMQP)的消息中间件,既支持单一节点部署,同时也支持多个节点的集群部署,在某种程度上完全可以满足目前互联网应用或产品高并发、大规模和高可用性的要求。

1.认识RabbitMQ

打开浏览器,输入地址:https://rabbitmq.com/打开,即可看到RabbitMQ的官网,如图:
RabbitMQ官网

可以官网上看出,称RabbitMQ是目前应用和部署“最”广泛的开源消息代理。在某种程度上说明其企业级系统中应用还是很广泛的。RabbitMQ在如今盛行的分布式系统中主要起到存储分发消息、异步通信和解耦业务模块等作用,在易用性。扩展性和高可用等方面均表现不俗。
值得一提的是,RabbitMQ是一款面向消息而设计的、遵循高级消息队列协议的分布式消息中间件,其服务端是采用Erlang语言开发的,支持多种编程语言的应用系统调用其提供的API接口。
除此之外,RabbitMQ的开发团队还为其内置了人性化的后端管理控制台,或者称为“面向开发者的消息客户端”,可以用于实现RabbitMQ的队列、交换机、路由、消息和服务节点的管理等,同时也可以提供客户端管理相应的用户(主要是分配相应的操作权限和数据管理权限等)。

2.应用场景介绍

RabbitMQ作为一款能实现高性能存储分发消息的分布式中间件,具有异步通信、服务解耦、接口限流、消息分发和业务延迟处理等功能,在实际生成环境中具有广泛的应用,其特性可以概括为如下图所示:
RabbitMQ的作用

2.1.异步通信和服务解耦

以“用户注册”为实际场景,传统的企业级应用处理用户注册的流程,首先是用户在界面上输入用户名、邮箱或者手机号等信息,确认无误后,单机“注册”按钮提交相关信息,前端将这个信息提交到后端相关接口进行处理,后端接收到这些信息后,会先对这些信息进行最基本的校验,校验成功后将信息写入数据库相关数据表中,而为了用户注册的安全性,后端会调用邮件服务器提供的接口发送一封邮件验证用户的合法性,或者调用短信服务的发送短信验证码接口给用户进行验证,最后才将响应信息返回给前端用户,并提示“注册成功”,这个流程如下图所示:

传统的企业级应用系统用户注册流程
从上图中的流程可以看出,用户从单击“注册”按钮,提交相关信息之后便需要经历“漫长”的等待时间,整体的等待时间约等于“写入数据库”+“邮箱验证”+“短信确认”的处理时间之和。在处理过程中如果发邮件和发短信业务逻辑出现异常,整个流程将会终止,很显然这种处理方式对于当前互联网用户来说几乎不可能接受!
仔细分析用户注册的这个流程,不难发现其核心的业务逻辑在于“判断用户注册信息的合法性并将信息写入数据库”,而“发送邮件”和“短信验证”服务在某种程度上并不归属于“用户注册”的核心流程,因而可以将相应的服务从其中解耦出来,并采用消息中间件RabbitMQ进行异步通信,新流程如下图所示:

引入RabbitMQ消息中间件后用户注册流程

可以从上图看出引入RabbitMQ后,将“一条线走到底”的业务服务模块进行了解耦,系统接口整体响应时间也明显降低了很多,即实现了“低延迟”。这将给用户带来很好的体验效果。

2.2.接口限流和消息分发

以“商城用户抢购商品”为例,商城为了吸引用户流量,会不定期的举办线上商城热门商品的抢购活动,当抢购活动开始之前,用户犹如“守株待兔”一般会盯在屏幕前等待活动的开始,当活动开始之时,由于商品数量有限,所有的用户几乎会在同一时刻单击“抢购”按钮进行商品的抢购,整体流程如下图所示:

商城商品抢购活动传统的处理流程

毫无疑问,在抢购活动开始的那一刻,将会产生巨大的用户抢购流量,这些请求几乎在同一时间到达后端系统接口,而在正常情况下,后端系统接口在接收到前端发送过来的请求时,会执行以下流程:
首先会校验用户和商品等信息的合法性,当校验通过之后,会判断当前商品的库存是否充足,如果充足,则代表当前用户将能成功抢购到商品,最后将用户抢购成功的相关数据插入数据库,并异步通知用户抢购成功,尽快进行付款等操作。
然而,通过仔细分析发现,后端系统接口在处理用户抢购的整体业务流程“太长”,而在这整块业务逻辑处理国产中,存在着先取出库存再进行判断,最后再进行减1的更新操作,在高并发的情况下,这些业务操作会给系统带来诸多的问题。比如,商品超卖、数据不一致、用户等待时间长、系统接口挂掉等现象。因而这种单一处理流程只适用于同一时刻请求量很少的情况,而对于类似商城抢购、商品秒杀等某一时刻产生高并发请求的情况则显得力不从心了。
消息中间件RabbitMQ的引入可以大大的改善系统的整体业务流程和性能,如下图所示,引入RabbitMQ后系统的整体处理流程:

引入RabbitMQ的商城抢购活动流程

由上图可以看出,RabbitMQ的引入主要从以下两个方面来优化系统的整体处理流程:
(1)接口限流:当前端产生高并发请求时,并不会像“无头苍蝇”一样立即到达后端系统接口,而是像每天上班时的地铁限流一样,将这些请求按照先来后到的规则加入RabbitMQ的队列,即在某种程度上实现“接口限流”。
(2)消息异步分发:当商品库存充足时,当前抢购的用户将可以抢到该商品,之后会异步的通过发送短信、发送邮件等方式通知用户抢购成功,并告知用户尽快执行后续操作,即在某种程度上实现了“消息异步分发”。

3.业务延迟处理

RabbitMQ除了可以实现消息实时异步分发之外,在某些业务场景下,还能实现消息的延时和延迟处理。以“春运12306抢票”为例,春运抢票相信大家都不陌生,当我们在使用12306抢票软件抢到火车票时,12306官方会提醒用户“请在30分钟内付款”。正常情况下用户会立即付款,然后输入相应的支付密码支付火车票的价格。扣款成功后,12306官方会发送邮件或者短信,通知用户抢票成功和付款成功。
然而,实际却存在着一些特殊情况,比如用户抢到车票后,由于各种原因迟迟没有付款,过了30分钟后仍然没有支付车票款项,导致系统自动取消该笔订单。类似这种“需要延迟一定时间后再进行处理”的业务在实际生产环境中并不少见,传统企业级应用对于这种业务的处理,是采用一个定时器定时去获取没有付款的订单,并判断用户的下单时间距离当前时间是否超过30分钟,如果是,则表示用户在30分钟内仍然没有付款,系统将自动使该笔订单失效并回收该张车票,整个业务流程如下:

抢票成功后30分钟内未付款的传统处理流程

春运抢票完全可以看作是一个大数据量、高并发请求的场景,在某一时刻车票开抢之后,正常情况下将陆续会有用户抢到车票,但是距离车票付款成功是有一定的时间间隔的。在这段时间内,如果定时器频繁的从数据库中获取“未付款”状态的订单,其数据量之大将难以想象,而且如果大批量的用户在30分钟内迟迟不付款,那从数据库中获取的数据量将一直增长,当达到一定程度时,将给数据库服务器和应用服务器带来巨大的压力,更有甚者将直接压垮服务器,导致抢票等业务全线崩溃,带来的直接后果将不堪设想!
早期的很多抢票软件每当赶上春运高峰期时,经常会出现“网站崩溃”、“单击购买车票后却一直没响应”等状况,某种程度上是因为在某一时刻产生的高并发,或者定时频繁拉取数据库得到的数据量过大等状况,导致内存、CPU、网络和数据库服务等负载过高所引起的。
而消息中间件RabbitMQ的引入,不管是从业务层面还是应用的性能层面,都大大得到了改善,如下图所示为引入RabbitMQ消息中间件后的抢票成功后30分钟未付款的处理流程优化:

抢票成功后30分钟未付款的优化处理流程

从上图优化流程中可以看出,RabbitMQ的引入主要是替代了传统处理流程的“定时器处理逻辑”。取而代之的是采用RabbitMQ的延迟队列进行处理。延迟队列,顾名思义指的是可以延迟一定的时间再处理响应的业务逻辑。
RabbitMQ的这一特性在某些场景下确实能起到很好的作用,比如上面例子讲到的“成功抢票后30分钟未付款处理流程”就是比较典型的一种。除此之外,商城购物时“单击去付款而迟迟没有在规定的时间内支付”的流程处理、点外卖“下单成功后迟迟没有在规定时间内付款”的流程处理等都是实际生产环境中比较典型的场景。