浅谈Java架构中的消息中间件

Posted 架构世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈Java架构中的消息中间件相关的知识,希望对你有一定的参考价值。

消息中间件是互联网系统里最常见的中间件了。有RabbitMQ、ActiveMQ等等。一般考虑使哪个消息中间件时,我们除了看中间件成熟度,还要考察它是广泛性、支持度等等。比如一个系统里有JAVA软件,又有Python软件,还有php等多种语言,我们就要选择能够支持广泛语言系列的中间件。

比如说:RocketMQ是基于Java语言开发的,经过阿里的精心打造能够应对高并发情况。有必要时可以研究源码,了解其内部实现原理。但是正因为如此,RocketMQ只支持Java和C++(据说现在有了python的客户端了),系统里如果有其它语言做的微服务就不能考虑它。RabbitMQ和ActiveMQ支持比较广泛。但是RabbitMQ是Erlang开发的,读源码的难度就相对高一点点。我们可以参考下图


消息中间件最简单的作用就是系统解耦。如果没有消息中间件,A系统要和B系统通讯,B系统和C系统通讯,各个系统间有着极强的耦合度。如果有200个微服务系统,那程序员简直要疯掉。现在用了消息中间件,大家把消息放在中间件队列中,其它系统各取所需,之间耦合度降低,系统风险和复杂度都降低了。

还有,利用消息中间件可以实现流程的异步处理。比如说一个外卖系统,平台的流程是这样的:A:用户下单 B:平台接单 C:平台给餐厅下单 D:平台找到附近的骑手 E:平台给骑手下单 F:骑手接单 G:确认订单

假设都是这样顺序操作,平台先定位每个骑手位置,再用餐厅位置来判断谁离得近,大家可以想象这个算起来还是挺费时间的。平台算了3分钟找到了骑手,骑手再确认订单,5分钟可能就过去了 - 这对争分夺秒的送单来说可是很重要的5分钟啊!再说用户5分钟后才能收到确认订单,肯定等不耐烦了。

用消息中间件处理,就简单了。用户需要的并不是确认某个骑手送过来,只是确认可以送就好。于是流程从A - G变成了ABC和DEF并行处理,DEF可以随时进行,这样用户从下单到确认速度就快多啦!

浅谈Java架构中的消息中间件

大家一起跑吧!

而且呢,中间件还有一个重要的作用:流量削峰。比如说你有一个系统,平时收到的请求只有几百个,CPU跑不满,但是每天某个时段突然来了几百万个请求,这时候CPU处理不过来了,只能加服务器,但是每天只有那么短暂的一个时间是几百万请求过来,加一堆服务器很浪费对吧?这时候我们部一个MQ来接收请求,然后发给系统慢慢处理,这样用很低的成本我们就应对了流量高峰。


说了半天,都是消息中间件的好处,当然了坏处也肯定有。从系统工程角度来看,引入了消息中间件,系统的不稳定因素就多了一个 - 中间件也有可能会出问题啊!而且之前紧耦合关系由中间件拆成松耦合,消息中间件如果挂掉了对整个系统影响可是巨大的。这就需要我们对中间件进行高可用设置(可用看看之前TCC的文章)。

在一个复杂系统里,可能会有这种情况发生:比如用户下了订单,支付系统就会向库存系统发生一条消息,你该向某某某发快递啦!可是这时候库存系统的MQ宕机了,库存系统没有收到这条消息,怎么办?

想想双11剁手买的iPhoneX,过了10多天还没有发货,哪个消费者都火大了,所以维持系统的高可靠运行是十分有必要的。

回到上面问题,就是一个ACT状态自动设置的问题。订单发送消息,应当只有库存系统收到并回复OK了,才应该删除掉这条消息。但是有的消息中间件比如RabbitMQ就会在库存系统收到消息后立马把这条订单消息给标记为删除。但是这时候实际上并没有发货呢,假设库存系统这时候正好收到消息了却出了问题,重启服务以后消息没有了,它就不知道应该发货了。

所以我们要修改默认配置,比如

把basicConsume的默认自动删除关闭掉,改为false,只有发货系统收到消息,并且发货后发出回应ack消息,MQ删除掉对应发货信息,这样就能保持系统高稳定了。

所以在部署消息中间件时,我们需要考虑:

1、什么样的消息中间件是最适合我们的?

2、消息中间件的默认配置如何?如何有机的和业务系统配合起来

3、如何确保系统LA高度可靠的运行?

我们会在后面的文章中逐渐讲解如何构筑高可用消息中间件系统


以上是关于浅谈Java架构中的消息中间件的主要内容,如果未能解决你的问题,请参考以下文章

浅谈消息队列及常见的消息中间件

浅谈消息队列及常见的消息中间件技术

小白快速入门消息中间件

架构优化之从BAT实际案例看消息中间件的妙用

高并发系列:架构优化之从BAT实际案例看消息中间件的妙用

以ActiveMQ为例JAVA消息中间件学习——消息中间件实际应用场景