云原生技术分享 | 带你走进RocketMQ的世界

Posted 兴兵乐儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生技术分享 | 带你走进RocketMQ的世界相关的知识,希望对你有一定的参考价值。

导语


云原生技术部落第四波主题文章来袭!RocketMQ系列文章将为大家分享开源消息队列中间件RocketMQ的知识与实践,不仅有RocketMQ的多种用法、生产环境的实际部署,还会有RocketMQ的底层原理,千万不要错过哦!


文章作者 / 银银科技研发中心 李强进、高海隆


Part 1

消息中间件的作用


消息队列中间件(简称消息中间件)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等等功能,其作为分布式系统架构中的一个重要组件,有着举足轻重的地位。

在讲消息中间件之前,我们可以思考现实生活中的一个问题,星巴克是如何处理订单的呢?


与大多数商业公司一样,星巴克主要关心的也是订单最大化,更多的订单就意味着更多的收入。因此,他们采用异步的方式处理订单:点好咖啡后,收银员会拿出一个杯将你的订单在杯子上做个标记,然后将杯子放到一个队列,这里所说的队列其实就是咖啡机上的一排杯子。队列将收银员和咖啡师解耦,使收银员能够不断接单。享受异步带来的好处的同时,星巴克也需要解决异步方式内在的挑战。例如,咖啡制作完成的顺序不一定与下单的顺序一致。因此,星巴克会面临咖啡与顾客之间的关联问题。咖啡制作完成的顺序是不确定的,需要将每一杯咖啡分别对应到正确的顾客。

星巴克解决这个问题的方式与我们在消息系统中所使用的模式是一样的:使用某种关联ID。大部分星巴克都会将顾客的名字或者咖啡的类型作为显式关联ID写到杯子上,这个ID就类似于消息队列里面的messageId。可以发现,日常生活中星巴克杯子队列的功能就类似于我们系统中消息中间件的功能。

消息中间件主要有以下几个功能:

1、 异步化提升性能

异步化是如何提升性能的呢?一起来看下图。



没有引入中间件的时候,用户发起请求到系统A,系统A耗时20ms,接下来系统A调用系统B,系统B耗时200ms,带给用户的体验就是,一个操作全部结束一共耗时220ms。

如果引入中间件之后呢?


云原生技术分享 | 带你走进RocketMQ的世界


用户发起请求到系统A,系统A耗时20ms,发送消息到MQ耗时5ms,返回结果一共用了25ms,用户体验一个操作只用了25ms,而不用管系统B什么时候去获取消息执行对应操作,这样比较下来,性能自然大大提高。

2、 解耦

我们看下图:


云原生技术分享 | 带你走进RocketMQ的世界


如果没有引入中间件,那么系统A调用系统B的时候,系统B出现故障,导致调用失败,那么系统A就会接到异常信息,接到异常信息后肯定要再处理一下,返回给用户失败请稍后再试,这时候就得等待系统B的工程师解决问题,一切都解决好后再告知用户可以了,再重新操作一次吧。这样的架构,两个系统耦合再一起,用户体验极差。

那么我们引入中间件后是什么样的场景呢,看下面的流程:


云原生技术分享 | 带你走进RocketMQ的世界


对于系统A,发送消息后直接返回结果,不再管系统B后边怎么操作。而系统B故障恢复后重新到MQ中拉取消息,重新执行未完成的操作,这样一个流程,系统之间没有影响,也就实现了解耦。


3、 流量削峰

下面我们再聊聊最后一个场景,流量削峰。


云原生技术分享 | 带你走进RocketMQ的世界


假如我们的系统A是一个集群,不连接数据库,这个集群本身可以抗下1万QPS。系统B操作的是数据库,这个数据库只能抗下6000 QPS,这就导致无论系统B如何扩容集群,都只能抗下6000 QPS,它的瓶颈在于数据库。假如突然系统QPS达到1万,就会直接导致数据库崩溃,那么引入MQ后是怎么解决的呢,见下图:


云原生技术分享 | 带你走进RocketMQ的世界


引入MQ后,对于系统A没有什么影响,给MQ发送消息可以直接发送1万QPS。

此时对于系统B,可以自己控制获取消息的速度,保持在6000 QPS以下,以一个数据库能够承受的速度执行操作,这样就可以保证数据库不会被压垮。当然,这种情况MQ中可能会积压大量消息。但对于MQ来说,是允许消息积压的,等到系统A峰值过去,恢复成1000 QPS时,系统B还是在以6000 QPS的速度去拉取消息,自然MQ中的消息就慢慢被释放掉了,这就是流量削峰的过程。在电商秒杀、抢票等等具有流量峰值的场景下可以使用这么一套架构。

下面我们举一个在真实生产环境使用消息中间件的例子。

下图是一个电商订单系统的核心逻辑图,如果不使用消息中间件会出现什么问题呢?首先就是付款成功后订单系统需要调用库存系统减少库存,调用仓储系统发货,调用积分系统增加积分,调用短信系统发送短信等。如果这些系统的接口变更了,那么订单系统就得同步修改调用接口,也就是说订单系统跟其它各系统是耦合在一起的。另外电商遇到双11大促或者秒杀活动,访问请求量突然飙升,数据库会遇到瓶颈。这时候如果引入消息中间件,订单系统付款成功后只需要发送消息给各系统,就可以实现解耦,整个系统的响应速度会大大加快。在双11大促等访问量飙升的情况下控制消费消息的速度就可以实现访问流量削峰。


云原生技术分享 | 带你走进RocketMQ的世界


Part 2

常用消息中间件比较


目前国内常见的消息中间件主要有Kafka、RabbitMQ、RocketMQ。

Kafka的数据吞吐量是最好的,在常规的机器配置下,单台机器可以达到每秒十几万的QPS,集群可以达到几十万甚至上百万的QPS,但是Kafka也有一些不足之处。首先为了保证数据写入性能,Kafka是基于操作系统的页缓存来实现文件写入的。操作系统本身有一层缓存,叫做page cache,是在内存里的缓存,我们也可以称之为os cache,就是操作系统自己管理的缓存。在写入磁盘文件的时候,可以直接写入这个os cache里,也就是仅仅写入内存中,接下来由操作系统自己决定什么时候把os cache里的数据真的刷入磁盘文件中,所以Kafka实际上数据真正写入磁盘是异步的。如果机器故障了,可能会导致磁盘缓冲区的数据丢失,在一些关键性的业务系统里面,丢失数据会造成比较严重的后果,这种场景下就不适合使用Kafka了。

另外,Kafka功能比较单一,主要是支持发送消息给它,然后从里面消费消息,其它就没有什么额外的高级功能了。所以目前Kafka在各公司的使用一般是把Kafka用在用户行为日志的采集和传输上,比如大数据团队要收集APP上用户的一些行为日志,就可以使用Kafka来收集和传输。因为那种日志适当丢失数据是没有关系的,而且一般量特别大,要求吞吐量高,一般就是收发消息,不需要太多的高级功能。


Kafka异步刷盘机制


RabbitMQ的优势在于可以保证数据不丢失,也能保证高可用,然后支持部分高级功能,比如死信队列、消息重试,事务消息等。RabbitMQ文档非常完善,可视化管理界面功能丰富,使用方便。在对并发场景要求不是特别高的场景下,RabbitMQ是一个非常不错的选择。RabbitMQ的不足之处在于吞吐量比较低,一般就是每秒几万的级别,所以在遇到特别高并发的情况下,支撑起来是有点困难的。另外RabbitMQ进行集群扩展会比较麻烦,RabbitMQ的开发语言为erlang,因此也不容易阅读或者修改源代码,所以现在很多大公司都切换到RocketMQ了。

RocketMQ的消息吞吐量很高,单机可以达到10万QPS以上,而且可以部署大规模的集群保证高可用性,通过配置可以保证消息绝对不丢失,还支持各种高级功能,比如延迟消息、事务消息、消息回溯、死信队列、消息积压等。RocketMQ基于Java开发,因此很容易阅读它的源代码,甚至在有需要的时候修改源码。下面我们介绍一下RocketMQ的基本架构和原理。


Part 3

RocketMQ介绍


RocketMQ是阿里开源的消息中间件,它主要由NameServer、Producer、Broker、Consumer四部分构成。

NameServer:NameServer主要负责Broker、Topic和路由信息的管理,功能类似Dubbo的zookeeper。

Broker:消息存储中心,负责存储消息。

Producer:消息生产者,负责产生消息。

Consumer:消息消费者,负责消息消费。



假设RocketMQ部署在一台机器上,一般来说单机能支持10万+的QPS。如果大量的系统都要往RocketMQ里高并发写入消息,每秒可能会有几十万的请求,就需要采用集群化部署,将请求分散到多台机器上。

为了保证MQ的高可用,RocketMQ的Broker采用了主从架构以及多副本策略,Broker是有Master和Slave两种角色的,Master Broker收到消息后会同步给Slave Broker,这样Slave Broker上就能有一模一样的一份副本数据,这个时候如果任何一个Master Broker出现故障,可以保证数据不丢失,还能继续对外提供服务,保证了MQ的可靠性和高可用性。

对于系统来说,要发送消息到MQ里面去,还还要从MQ里面消费消息,那么怎么知道有哪些Broker呢?怎么知道要连接到哪一台Broker上去发送和接受消息?RocketMQ为了解决这个问题,有一个NameServer的概念,所有的Broker都会把自己的信息注册到NameServer。对于我们的系统而言,如果要发送消息到Broker,会找NameServer去获取路由信息,如果要消费消息,也需要根据NameServer去获取路由信息,然后从指定的Broker获取消息消费。

以上就是RocketMQ的基本原理和基本架构。下一讲,我们将详细讲解在生产环境下的高可用RocketMQ集群部署方案。


推荐阅读



以上是关于云原生技术分享 | 带你走进RocketMQ的世界的主要内容,如果未能解决你的问题,请参考以下文章

云原生 | Docker篇《带你走进Docker的世界》轻松学会原理|架构|安装|加速

云原生 | Docker篇《带你走进Docker的世界》轻松学会生存技巧 -> 命令

云原生 | 初识篇带你走进Docker的未知宇宙

瞄一眼,带你走进SparkSQL的世界

简化后端:一篇带你走进云开发及小程序云开发的世界

2021年零基础带你走进nacos的世界之云服务器下载安装nacos-小白教程,详细到爆了!