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

请不要在面试的时候问我SpringCloudAlibaba的底层原理

时间:2023-03-18 18:00:41 科技观察

大家好,今天给大家介绍一个很火的技术,也是面试官在面试的时候特别喜欢问的一个话题,那就是SpringCloudAlibaba底层原理。现在大家都知道SpringCloudAlibaba在Java开发行业很火,各个公司都在用这个技术,所以我们Java工程师出门面试的时候,面试官就把SpringCloudAlibaba列为面试必选项目。每当有面试的时候,面试官总会问问题:“兄弟,你玩过SpringCloudAlibaba吗?能说说SpringCloudAlibaba的底层原理吗?”这时候你要是一脸疑惑的说:“大哥,我们玩的是SpringCloud,为什么后来还要加Alibaba,这东西什么时候和Ali勾搭上了?”如果你在面试的时候这样回答,那么恭喜你,基本上面试官应该借口肚子痛去厕所,然后30分钟结束面试。所以,在这篇文章中,我们希望兄弟们不要出现30分钟被强制结束面试的尴尬问题。今天就让大家一步步了解SpringCloudAlibaba中包括了哪些技术组件,以及它们在系统中的作用,然后为大家分析这些技术的底层原理。首先,假设你的公司有两个系统,假设是A系统和B系统,这两个系统目前的需求是让A系统向B系统发送请求,实现系统之间的接口调用。我们看下图:现在有个最大的问题,系统A部署在一台服务器上,系统B部署在另一台服务器上,系统A怎么知道系统B部署在哪台机器上呢?这就好比说,你走在大马路上,看到一个美女,回到家想联系她微信,却连她的微信都不知道,也没加好友,你总不能凭空搭讪美女吧!那么搭讪美女的正确姿势应该是怎样的呢?这肯定有一个前提,就是你中间有认识美女的朋友,有微信公众号。这时候,你就可以找到中间的朋友,你需要去他们的微信,然后根据微信添加其他漂亮的朋友,就可以实现无缝的情感沟通!开个玩笑,以上只是一篇无聊的技术文章中的一个小插曲,其实对于你的系统来说,有必要介绍一下SpringCloudAlibaba的一个关键技术组件Nacos。请擦亮眼睛,这个Nacos是一个关键词,大家一定要记住它的学术定位叫“服务注册中心”。这个Nacos类似于上面说的那个拥有漂亮微信的第三方好友。他知道你的B系统部署在哪台机器上,因为B系统启动的时候会主动去Nacos服务注册中心注册。告诉Nacos你部署在哪台机器上,你机器的ip地址是172.86.76.251,你的端口号是20880。看下图:这时候A系统要调用B系统的接口,可以向Nacos服务注册中心发送请求说,兄弟,你能告诉我系统B部署在哪台机器上吗?我想称他为这个动作的界面,有一个专业术语叫“服务发现”。那么Nacos服务注册中心肯定会大方的给你系统B的微信号。哦,不对,告诉你的是系统B的机器ip和端口号。这时系统A知道了系统B的ip地址和端口号,可以发送请求调用系统B的接口过去。请看下图:我们来看下一题,假设系统B是美女,然后有多个双胞胎姐妹花,也就是说系统B部署在多台服务器上。这种情况我们称之为B系统在多台服务器上部署了多个服务实例,那么此时A系统要调用B系统,怎么办?我们看下图:其实很简单。系统B的每一个服务实例在部署一台机器后,都要向Nacos服务注册中心发起服务注册请求,所以Nacos就知道了系统B部署的每台机器的ip地址和端口号,见下图。那么当系统A找到Nacos进行服务发现时,它会立即发现系统B部署在两台机器上,也就是说,他会找到两台机器的ip地址和端口号。这时候,问题就来了。系统A很犹豫。B系统应该调用哪台机器?这很简单。可以第一次调用机器1,第二次调用机器2,第三次调用机器1,第四次调用机器1。从机2,依次类推,这个过程称为负载均衡,系统A可以通过负载均衡将自己的所有请求平均分配给系统B的每台机器,如下图。那么下一个问题又来了。如果系统A要调用系统B的一个接口,就必须和系统B建立网络连接,然后通过这个网络连接向系统B发送请求。B系统收到请求后,以后会调用本地某个接口的代码,然后通过网络连接将响应结果返回给A系统。这个过程称为RPC远程调用,见下图。其实这个RPC调用的过程,说白了,就类似于微信上跟人聊天的过程。微信聊天都要先加好友,然后发消息过去,然后他们再给你回消息?是的,我们这里的RPC调用也是如此。你得先在两台机器之间建立网络连接,然后系统A发送请求,系统B执行本地代码,然后返回响应给你。现在的问题是系统A需要在系统B部署的多台机器上实现负载均衡,然后建立网络连接,然后发起RPC调用,即系统A发送请求,系统B执行代码并返回一个回应。谁负责这个看似复杂的过程?简单,就是SpringCloudAlibaba中的另一个关键组件,Dubbo。这个Dubbo是一个RPC框架,负责帮你做负载均衡,网络连接,RPC调用。这是SpringCloudAlibaba组件体系中的第二个关键组件。我们看下图:那么我们来讨论下一个问题。很多人可能知道也可能不知道,那就是:4核8G的服务器每秒能抗多少个并发请求?有的兄弟平时玩的太高并发系统应该知道这个值,也就是说,如果是4核8G服务器上部署的java系统,java系统连接的是MySQL数据库,那么一般来说,这个服务器可以大致抵抗1000以内的QPS,如下图,我也把每秒1000个请求标记为红色。为什么是这样?原因很简单。我们需要从两个维度来分析:第一个维度就是我们的系统A有多少个线程来处理请求,每个请求需要多少ms来完成,每个线程每秒可以执行多少个请求。第二个维度就是我们系统A的n个多线程在拼命的处理请求。这个时候机器的CPU负载会有多大的压力。当所有线程每秒处理很多请求时,机器的CPU将无法处理。解决完这两个问题,你就知道系统每秒能抗多少请求了。先来看第一个维度。系统A一般通过Tomcat等web服务器对外接受用户请求,并提供controller等接口供外部使用springmvc,接收的所有HTTP请求。所以其实一般情况下,我们会在tomcat中配置200个左右的线程,也就是说系统A有200个线程会并发处理用户的请求,如下图所示。那么下一个问题来了:tomcat线程处理一个请求需要多长时间?这个不好说,因为一个线程在处理一个请求的时候,往往会执行很多你写的业务代码,从controller到service再到dao,如果你用mybatis作为数据持久层框架,应该用mybatismapper执行大量的SQL语句。往往取决于你的系统代码有多复杂,执行的SQL语句有多复杂,要执行多少条SQL,数据库中的表数据是几万、几十万、几百万,甚至几千万、亿等级。所以影响因素太多了,这里取一个不多不少的平均值,假设你一个请求需要调用数据库n次,执行n条SQL语句,数据库的数据量还是小,基本在十万到百万级别,那么你这时候处理一个请求大概需要200ms左右,如下图。所以一个简单的小学公式就可以算出来了。一个线程处理一个请求需要200ms,那么你每秒可以处理5个请求。如果你有200个线程,每秒可以处理200*5=1000个请求。小学水平的算术你没问题吗?所以,按照这个维度,系统A部署在一个4核8G的系统上,连接MySQL数据库,然后开启200个tomcat线程处理请求,每秒处理1000个请求是比较合理的。那么二次元呢?从CPU负载来看,其实也差不多。这是算术无法计算的。我只能告诉你一个经验值,就是当你的系统部署在4核8G的机器上,连接MySQL数据库,然后每次请求执行一堆SQL语句的时候,往往你的系统处理1000左右每秒请求数,您的机器CPU负载将达到80%甚至90%的利用率。系统负载已经很高了,机器完全不可能处理更多的请求。好了,那么对于这个系统A每秒可以处理1000个请求的经验值,我们来考虑一个问题,万一你们公司组织一个活动,突然每秒有2000个请求,或者是被黑了一次攻击,请求的数量每秒很大,你这时候怎么办?很明显你的系统A会被kill掉,如下图:那么这个时候我们应该怎么办呢?SpringCloudAlibaba中的第三个组件我们不得不介绍一下,它就是Sentinel,这个Sentinel就是帮助你的系统实现流量保护的。当你在系统A加入Sentinel后,如果每秒的请求超过1000,Sentinel会直接帮你直接拒绝那些多出来的请求。这个叫做限流,限制你的系统可以处理的请求数,这样你就可以保护你的系统不被杀掉,如下图。现在我们已经搞清楚了SpringCloudAlibaba中三个组件的运行原理和使用场景。Nacos是服务注册中心,Dubbo是RPC调用框架,Sentinel是流量防护组件。接下来我们来看最后一个组件,也就是Seata。正式交易组件。既然提到了分布式事务,那肯定和事务有关。这个事务相信大家都知道,就是我们可以为MySQL开启一个事务,在事务中执行n条SQL。如果有任何一条SQL失败,事务就会回滚,这n条SQL都不生效。但是在A系统调用B系统的分布式场景下,事务会怎样呢?我们看下图。假设A系统在处理请求时,首先在自己的数据库上执行了一堆SQL并提交了事务A,然后通过Dubbo向B系统发起RPC调用,B系统在自己的数据库上执行了一堆SQL,并且那么现在问题来了,假设我的系统A的事务A已经提交了,到了系统B的时候,事务B执行失败,事务B回滚了,怎么办呢?也就是说一个请求的处理是不一致的,一个系统的事务提交成功无法回滚,另一个系统的事务失败了!不用着急,只要引入Seata分布式事务框架,就可以轻松解决这个问题。Seata框架会自动记录你事务A执行的SQL语句的逆向补偿SQL,什么意思?假设你的事务A执行了insert,那么Seata在补偿的时候就知道可以delete了。假设你执行一次更新,Seata可以记录更新前的旧数据,补偿时重新更新回旧版本数据,反向补偿日志也记录在数据库中,如下图.那么Seata也会提供一个Seata服务器来监控你的每一个系统的事务执行状态。如果系统A的事务A执行成功,你必须告诉Seata服务器,如果系统B的事务B失败,你也必须告诉Seata服务器,如下图所示。当Seata服务器知道你B系统的事务B执行失败了,他会告诉A系统中的Seata框架,小兄弟,别人的B系统失败了,快点,别墨迹,把事务放上去A你之前记录的取出反向补偿日志,将你之前提交的事务恢复到提交前的数据状态,并进行反向回滚,如下图。好了,至此,我就给大家详细介绍一下SpringCloudAlibaba组件体系的几个组件的使用场景和工作原理,包括Nacos服务注册中心、DubboRPC调用框架、Sentinel流量保护组件、Seata分布式事务组件。看看上图,是不是很有成就感呢?