2024-02-02 09:51

RabbitMQ的应用场景

王姐姐

大数据

(401)

(0)

收藏

一.异步处理

场景:发送手机验证码,邮件

传统古老处理方式如下图

这个流程,全部在主线程完成,注册-》入库-》发送邮件-》发送短信,由于都在主线程,所以要等待每一步完成才能继续执行。由于每一步的操作时间响应时间不固定,所以主线程的请求耗时可能会非常长,如果请求过多,会导致IIS站点巨慢,排队请求,甚至宕机,严重影响用户体验。

现在大多数的处理方式如下图

这个做法是主线程只做耗时非常短的入库操作,发送邮件和发送短信,会开启2个异步线程,扔进去并行执行,主线程不管,继续执行后续的操作,这种处理方式要远远好过第一种处理方式,极大的增强了请求响应速度,用户体验良好。缺点是,由于异步线程里的操作都是很耗时间的操作,一个请求要开启2个线程,而一台标准配置的ECS服务器支撑的并发线程数大概在800左右,假设一个线程在10秒做完,这个单个服务器最多能支持400个请求的并发,后面的就要排队。出现这种情况,就要考虑增加服务器做负载,尴尬的增加成本。

消息队列RabbitMq的处理方式

 

这个流程是,主线程依旧处理耗时低的入库操作,然后把需要处理的消息写进消息队列中,这个写入耗时可以忽略不计,非常快,然后,独立的发邮件子系统,和独立的发短信子系统,同时订阅消息队列,进行单独处理。处理好之后,向队列发送ACK确认,消息队列整条数据删除。这个流程也是现在各大公司都在用的方式,以SOA服务化各个系统,把耗时操作,单独交给独立的业务系统,通过消息队列作为中间件,达到应用解耦的目的,并且消耗的资源很低,单台服务器能承受更大的并发请求。

二.应用解耦

以电商的下订单为例子,假设中间的流程为下单=》减库存=》发货

传统的做法是,订单系统调用库存系统的接口

传统做法的缺点:

1、假如库存系统无法访问,则订单减库存将失败,从而导致订单失败

2、订单系统和库存系统耦合

如何解决以上问题呢?引入应用消息队列后的方案,如下图

1、订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功

2、库存系统:订阅下单的消息,采用拉/推得方式,获取下单信息,库存系统根据下单信息,进行库存操作

3、假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦

一般常见的三种三种实现方案

第一种方式:

通过连续操作表,在单一系统中,通过主线程,连续操作。呵呵哒,这种做法,相信很多人刚入门,甚至几年经验了,由于项目小,也在继续使用吧。用户量少,或者都是内部人使用,必然没问题,因为不会在意出的问题,这种做法,只要一个环节出问题,请求直接报错,导致用户懵逼,假设在执行到减库存操作报错了,整个流程没有用事务回滚的话,还会造成数据不一致。

第二种方式:

把这三个业务,拆成三个独立系统,通过JSON方式相互调用请求。这个做法,其实已经很不错了,起码独立出来,各自做各自的事情,一定程度上减小了整个系统的耦合性。但是问题是,就算是通过API形式请求,发送请求的系统一般情况下会等待被请求方的响应,如果响应错了,整个程序还是会终止,前面的业务系统假如已经做了入库操作,就必须要混滚了。很麻烦。如果说不等待被请求方响应的话,如果出错,如果还要保证数据一致性,就要做更多的操作,去补全数据,比如,下单成功,减库存失败,发货成功,这样当减库存系统修复后,就要通过订单数据,去补库存表的对应数据。先对麻烦,难处理。

第三种方式:

把消息队列作为中间件,当订单系统下完单后,把数据消息写入消息队列中,库存系统和发货系统同时订阅这个消息队列,思想上和纯API系统调用类似,但是,消息队列RabbitMq本身的强大功能,会帮我们做大量的出错善后处理,还是,假设下单成功,库存失败,发货成功,当我们修复库存的时候,不需要任何管数据的不一致性,因为库存队列未被处理的消息,会直接发送到库存系统,库存系统会进行处理。实现了应用的大幅度解耦。

三.流量削峰

这个主要用在团购,秒杀活动中,一般会因为流量过大,导致流量暴增,应用挂掉

为解决这个问题,一般需要在应用前端加入消息队列:

1、可以控制活动的人数

2、可以缓解短时间内高流量压垮应用

这个主要原理就是,控制队列长度,当请求来了,往队列里写入,假如超过消息队列的长度,就返回失败,给用户报一个可爱的错误页等等。

四.日志处理

这个场景应该都很熟悉,一个系统有大量的业务需要各种日志来保证后续的分析工作,而且实时性要求不高,用队列处理再好不过了

五.消息通讯

现在上线的各大社交通讯项目中,实际上是没有用消息队列做即时通讯的,但是它确实可以用来做,有兴趣的不妨去试试吧

点对点通讯:消费者A和B同时订阅消息队列,又同时是制造者,就能实现点对点通信

聊天室通讯:群聊的做法,所有客户端同时订阅队列,又同时是发送,制造者。

六.复杂业务处理

消息队列采用高可用,可持久化的消息中间件。

1、应用将主干逻辑处理完成后,写入消息队列。消息发送是否成功可以开启消息的确认模式;

2、扩展流程(发短信、配送处理)订阅队列消息,采用拉或推得方式获取消息并处理;

3、消息将应用解耦的同时,带来了数据一致性的问题,可以采用最终一致性方式解决。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

上述大致的5种RabbitMq的应用场景,下面来介绍几个消息队列的区别

ActiveMq:这个应用于JAVA中间件较多

ZeroMq:这个是分发效率最高的队列,是其他队列的十倍以上,缺点是不能数据持久化。

kafka:这是一种高吞吐量的发布订阅消息系统,当每秒达到10W+的分发要求时,可以用这个尝试,新浪微博就是用这个做分发。

先写这么多吧,大致的应用场景,欢迎各路大神来补充,我也是公司需要,学习整理出来的,可能会有理解偏差,见谅哈!


0条评论

点击登录参与评论