个人博客


RabbitMQ作为目前应用相当广泛的消息中间件,在企业级应用、微服务应用中充当着重要的角色。特别是在一些典型的应用场景以及业务模块中具有重要的作用,比如业务服务模块解耦、异步通信、高并发限流、超时业务、数据延迟处理等都可以使用RabbitMQ

1、使用场景

1.1、发布/订阅

“发布/订阅”是RabbitMQ的重要功能,可以用”发布/订阅”功能来实现通知功能。消费者(consumer)一直监听RabbitMQ的数据。如果RabbitMQ有数据,则消费者会按照”先进先出”规则逐条进行消费。而生产者(producer)只需要将数据存入RabbitMQ。这样既降低了生产者应用和消费者应用之间的耦合度,也确保了消息通知的及时性。不需要生产者和消费者同时在线,且不影响系统的性能。

“发布/订阅”功能支持3种模式:一对一、一对多、广播。

解耦

看这么个场景。A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?

在这个场景中,A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来。A 系统要时时刻刻考虑 BCDE 四个系统如果挂了该咋办?要不要重发,要不要把消息存起来?

如果使用 MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。

总结:通过一个 MQ,Pub/Sub发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。

1.2、异步任务

如果在一次请求过程中,涉及多个任务,其中一些任务可能会比较耗时,但这些任务的执行顺序并不影响整个业务的处理结果,则可以把这些耗时的任务放入消息队列中去处理,以便加快请求的响应速度。

比如一些网站的注册功能,需要发送邮件/短信验证码,则可以使用RabbitMQ的消息队列来实现,这样可以及时提醒用户操作已经成功,等待收到验证码验证即可。

1.3、削峰填谷

每天 0:00 到 12:00,A 系统风平浪静,每秒并发请求数量就 50 个。结果每次一到 12:00 ~ 13:00 ,每秒并发请求数量突然会暴增到 5k+ 条。但是系统是直接基于 MySQL 的,大量的请求涌入 MySQL,每秒钟对 MySQL 执行约 5k 条 SQL。

一般的 MySQL,扛到每秒 2k 个请求就差不多了,如果每秒请求到 5k 的话,可能就直接把 MySQL 给打死了,导致系统崩溃,用户也就没法再使用系统了。

但是高峰期一过,到了下午的时候,就成了低峰期,可能也就 1w 的用户同时在网站上操作,每秒中的请求数量可能也就 50 个请求,对整个系统几乎没有任何的压力。

如果使用 MQ,每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求,因为 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过自己每秒能处理的最大请求数量就 ok,这样下来,哪怕是高峰期的时候,A 系统也绝对不会挂掉。而 MQ 每秒钟 5k 个请求进来,就 2k 个请求出去,结果就导致在中午高峰期(1 个小时),可能有几十万甚至几百万的请求积压在 MQ 中。


这个短暂的高峰期积压是 ok 的,因为高峰期过了之后,每秒钟就 50 个请求进 MQ,但是 A 系统依然会按照每秒 2k 个请求的速度在处理。所以说,只要高峰期一过,A 系统就会快速将积压的消息给解决掉。

总结:可以用MQ将大量的请求数据临时存起来,然后让消费端按照一定的速率慢慢去消费,可以有效减轻服务器部分时段的压力。

1.4、跨平台通信

由于消息队列是无关平台和语言的,而且语义上也不是函数调用,所以RabbitMQ可以用于不同开发语言开发的应用间的通信,实现企业应用集成。

1.5、消息延迟

当消息由生产者发出后,消费者不是立即拿到消息。而是等待指定时间后才拿到消息进行消费。

一般要实现消息队列的延迟功能,可以采用官方提供的插件rabbitmq_delayed_message_exchagne,但RabbitMQ版本必须是3.5.8以上才支持该插件,如果低于这个版本则可以利用死信队列来完成这个功能。

1.6、RPC(远程过程调用)

在实际的应用场景中,有时需要一些同步处理,以等待服务器端将消息处理完成后再进行下一步处理,这相当于RPC(Remote Procedure Call,远程过程调用)。