当前位置: 首页 > 科技观察

消息服务:MQ使用场景及选型对比

时间:2023-03-18 14:09:02 科技观察

上一篇我们实现了用户微服务、商品微服务、订单微服务之间的远程调用,实现了服务调用的负载均衡。还基于阿里开源的Sentinel实现了服务的限流和容错,详细介绍了Sentinel的核心技术和配置规则。简单介绍了服务网关,简单说明了SpringCloudGateway的核心架构。项目中还集成了SpringCloudGateway网关,实现通过网关访问后端微服务。Stream函数,详细介绍了SpringCloudGateway的核心技术。在链接跟踪章节中,我们简单介绍了分布式链接跟踪技术和解决方案,然后在项目中集成Sleuth实现链接跟踪,并利用Sleuth集成ZipKin实现分布式链接跟踪的可视化。今天,我们正式进入消息服务篇章。首先简单说一下MQ的使用场景,引入MQ后的注意事项,以及MQ的选型对比。本章概述了MQ的使用场景。MQ的英文全称是MessageQueue,翻译成中文就是消息队列。队列实现先进先出(FIFO)消息模型。通过消息队列,我们??可以实现多个进程之间的通信,比如可以实现多个微服务之间的消息通信。MQ最简单的模型就是生产者生产消息,向MQ发送消息,消息消费者订阅MQ,消费消息。MQ的使用场景通常包括:异步解耦和流量调峰。异步解耦关于异步场景,这里是用户下单成功后,给用户发送通知消息,为用户增加积分和优惠券的场景。同步耦合场景分析如果是同步调用场景,具体业务为:当用户提交订单成功后,订单系统会调用通知系统向用户发送消息通知,告知用户订单成功,订单系统会调用积分系统为用户增加积分,订单系统调用优惠券系统为用户添加优惠券。整个调用过程如下。通过上图的分析可以看出,用户调用订单系统下单时,一共会经历8个步骤。并且每个步骤都紧密耦合在一起并串行执行,如下所示。此时,订单系统、通知系统、积分系统和优惠券系统紧密耦合在一起。订单系统下单,通知系统发送通知,积分系统发送积分,优惠券系统发送优惠券。四个任务全部完成后,将提交订单的结果信息返回给用户。用户提交订单总耗时为调用订单系统下单时间+订单系统调用通知系统发送通知时间+订单系统调用积分系统发出时间积分+订单系统调用优惠券系统发放优惠券的时间。注:这里为了更好的说明系统间串行执行的问题,忽略了网络的延迟时间。这种串行化的系统执行方式在高并发、大流量的场景下不可取。此外,如果其中一个系统出现异常或宕机,势必会影响订单系统的可用性。在系统维护方面,只要任何一个系统的界面发生变化,订单系统的逻辑也会随之发生变化。异步解耦场景分析由于在高并发、大流量的场景下,不建议使用订单系统直接串行调用通知系统、积分系统、优惠券系统。那么我们可以使用异步解耦吗?其实在用户提交订单的场景下,用户最关心的是自己的订单是否提交成功,因为在下单的时候,订单系统会直接返回是否下单成功的提示。通知、奖励和优惠券可以在短时间内异步执行。并且通知系统、积分系统、优惠券系统之间没有必要的业务关联逻辑,可以并行执行。因此,可以使用MQ将订单系统与通知系统、积分系统、优惠券系统解耦。当用户调用订单系统接口下单时,订单系统将订单数据写入数据库,然后向MQ写入消息。直接给用户返回下单成功的提示。此时通知系统、积分系统、优惠券系统都订阅了MQ中的消息,收到消息后各自执行自己的业务逻辑。引入MQ异步解耦后,用户调用订单系统的接口下单。订单系统执行业务逻辑并导入订单数据后,会向MQ发送消息,然后直接返回用户下单成功的提示。通知系统、积分系统、优惠券系统会同时订阅MQ中的消息。当收到消息时,他们会各自执行自己的业务逻辑,他们会并行执行各自的业务逻辑。从执行时间线可以看出,引入MQ进行异步解耦后,通知系统、积分系统、优惠券系统、订单系统回复响应都是并行执行的,大大提升了系统的执行性能。并且解耦后,任何系统异常或宕机都不会影响订单系统的可用性。只要订单系统和其他系统事先约定好要发送的消息的格式和内容,后续任何系统的业务逻辑发生变化都几乎不会影响订单系统的逻辑。流量调峰MQ可以作为高并发大流量场景削峰填谷的利器,例如12306春节抢票场景,高并发秒杀场景,双十一、618大促场景等在高并发、大流量的业务场景下,大量的用户请求会瞬间涌入系统。如果不对流量进行处理,直接让流量进入下游系统,很可能下游系统无法支撑这么高的并发。导致系统崩溃或停机。为了解决这些问题,可以引入MQ来削峰填谷。流量上送MQ后,下游系统可以根据自己的处理能力进行消费。保证下游系统的高可用性。引入MQ后的注意事项引入MQ最大的好处就是异步解耦和流量削峰。但是引入MQ后需要注意的事项和问题很多,主要包括:系统整体可用性降低,系统复杂度增加,消息一致性问题的引入。系统的整体可用性降低。在设计系统的架构时,引入的外部依赖越多,系统的稳定性和可用性就会降低。当系统引入MQ后,一些业务会强烈依赖MQ。这时候如果MQ宕机,部分业务会不可用。所以,在引入MQ的时候,我们不得不考虑如何实现MQ的高可用。系统的复杂度变得更高。引入MQ后,之前的同步接口调用将变成通过MQ的异步调用。在实际开发过程中,异步调用会比同步调用复杂。而且异步调用出现问题后,重现问题、定位问题、解决问题都会比同步调用复杂很多。而且引入MQ之后,还需要考虑如何保证消息的顺序等问题。消息一致性问题引入MQ后,不得不考虑的问题之一就是消息一致性问题。这期间需要考虑如何保证消息不丢失,消息的幂等性和消息数据处理的幂等性。MQ选型对比目前业界使用较多的MQ有RabbitMQ、Kafka、RocketMQ。在这里,我简单整理了一张三者对比表,如下图。消息中间件(MQ)优缺点使用场景RabbitMQ功能全面,消息可靠性相对较高,吞吐量较低,大量消息堆积会影响性能。使用的开发语言是erlang,不太容易自定义功能。在小规模场景下,Kafka吞吐量最高,性能最好。集群模式下,高可用功能比较简单,会丢失一些数据日志分析。在大数据场景下,RocketMQ具有高吞吐、高性能、高可用、功能全面等特点。使用Java语言开发,方便自定义功能。开源版不如阿里云版,文档比较简单。几乎所有场景都支持,包括大数据场景和业务场景。