消息中间件入门
前言
本篇文章不涉及到代码,只是站在理论的角度上去思考,整理,更清晰的认识消息队列。
什么是消息中间件
其实并没有标准定义。一般认为,消息中间件属于分布式系统中一个子系统,关注于数据的发送和接收,利用高效可靠的异步消息传递机制对分布式系统中的其余各个子系统进行集成。
他的应用场景是什么
- 异步:
比如现在有一个电商平台下单的业务:用户生成订单之后点击付款按钮进行付款。这个操作对于后端的逻辑应该是这样的:
请求用户服务进行账户扣款 ----> 调用订单服务修改订单表的订单状态 ----> 调用库存服务扣减库存数 ----> 调用积分服务给用户增加积分 ----> 返回前端“付款成功”的提示信息。
这个逻辑是没有问题的,但是仔细想想,在服务器请求满载的情况下这么一套流程跑下来要多久,如果你是用户你能忍?那我们现在就来优化一下这个过程。首先分析一下,用户的请求是直接打在了用户服务的,当支付接口调用成功之后就表示用户的操作是没问题的,付款也是成功的,那么对于后续的修改订单状态、减库存、加积分这些操作其实我们可以以异步的方式执行,没必要非得一个一个排着队执行,因为触发这些操作的一个点是支付有没有成功。 - 解耦:
还是上面那个例子,当逻辑在增加积分那一步出现了问题,或者在新版本的迭代中积分服务的接口有变更,这时候在调用积分服务的时候就会出现异常,虽说用户付款成功了,但是响应前端的仍然是“支付失败”,其实这是不合理的,积分可以等一会再加,但是一定要保证用户目前的支付业务是正常的,所以可以把这些不相干的业务分离开,不进行接口的强制调用,要解耦但还要藕断丝连,服务之间通信进行消息的传递,当用户付款成功之后就往队列中发送一条付款成功的消息,其他服务监听到消息之后进行后续的业务处理,这样就保证了对支付服务很小的影响。 - 流量削峰:
这个场景其实还是很不错的,假设现在有一个秒杀的功能,我们服务端要做的是:
1、保证高并发下服务仍然可用;
2、保证商品不会超卖;
仔细分析一下:秒杀这种业务是瞬时请求,秒杀未开始的时候请求也很正常,当准点一到,几万甚至几十万上亿的请求突然进来,但是最终能抢到商品的只有几百或几千个,那我们为什么不可以将瞬时的请求按照先来后到把并发请求变成串行请求呢,手速快的网速快的先进入队列判断商品库存进行付款,后面手慢的就秒杀失败了。
当然消息队列的应用场景还有很多,分布式事务,延时订单的处理等高级用法,但是最常用的还是以上三种场景。
既然消息队列这么好,那我们干脆都用它好了;其实不然,人无完人,有优点也有缺点,下面我们就来总结一下他的优缺点:
- 系统的技术复杂度变高了,要考虑消息的可靠性消费,解决重复消费和消息丢失的问题。
- 无法做到实时性,如果系统对于数据实时性要求很高的话,消息队列显然就显的有点多余了。
什么是RabbitMQ
什么是RabbitMQ呢?鉴用百度的一句话:
RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。
那么AMQP又是什么呢?为了好理解,我就不套用百度了,简单来说AMPQ应用层协议的一个开放标准,,它制定了一套规范的消息服务器的模型,可以由不同的中间件去实现它,是为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。目标是实现一种在全行业广泛使用的标准消息中间件技术,以便降低企业和系统集成的开销,并且向大众提供工业级的集成服务,主要实现有RabbitMQ。
再用简单的话解释一下RabbitMQ:他是一个系统之间以解耦和异步的方式进行逻辑交互的一个中间平台,使用Erlang语言实现,系统之间可以不进行强依赖,只需要保证这个中间平台可以成功的将消息进行传递即可。
当然,消息中间件也不只有RabbitMQ,还有其他的比如:RocketMQ、Kafka、ActiveMQ、还有好多。。。。。
那么相比之下RabbitMQ的地位如何呢?看下图:
技术选型
实际工作中对于各种MQ的技术选型个人认为是这样的:
用户访问量在ActiveMQ 的可承受范围内,而且确实主要是基于解耦和异步来用的,可以考虑ActiveMQ,也比较贴近Java
工程师的使用习惯,但是ActiveMQ 现在停止维护了,同时ActiveMQ 并发不高,所以业务量一定的情况下可以考虑使用。RabbitMQ 作为一个纯正血统的消息中间件,有着高级消息协议AMQP 的完美结合,在消息中间件中地位无可取代,但是erlang
语言阻止了我们去深入研究和掌控,对公司而言,底层技术无法控制,但是确实是开源的,有比较稳定的支持,活跃度也高。对自己公司技术实力有绝对自信的,可以用RocketMQ,但是RocketMQ诞生比较晚,并且更新迭代很快,这个意味着在使用过程中有可能会遇到很多坑,所以如果你们公司Java 技术不是很强,不推荐使用。
中小型公司,技术实力较为一般,技术挑战不是特别高,用ActiveMQ、RabbitMQ是不错的选择;大型公司,基础架构研发实力较强,用RocketMQ是很好的选择
如果是大数据领域的实时计算、日志采集等场景,用Kafka 是业内标准的,绝对没问题,社区活跃度很高,几乎是全世界这个领域的事实性规范。
从性能上来看,使用文件系统的消息中间件(Kafka、RokcetMq)性能是最好的,所以基于文件系统存储的消息中间件是发展趋势。(从存储方式和效率来看文件系统>KV存储>关系型数据库)
没有不劳而获的工作,更没有坐享其成的收获,若比别人贪心,请比别人用心。