微服务相关面试题的分类:
一、SpringCloud
1.SpringCloud的5大组件都有哪些?
答:早期我们一般认为的Spring Cloud五大组件是:
Eureka : 注册中心
Ribbon : 负载均衡
Feign : 远程调用
Hystrix : 服务熔断
Zuul/Gateway : 网关
随着SpringCloudAlibba在国内兴起 , 我们项目中使用了一些阿里巴巴的组件 :
注册中心/配置中心 Nacos
负载均衡 Ribbon
服务调用 Feign
服务保护 sentinel
服务网关 Gateway
2.服务注册和发现是什么意思?SpringCloud如何实现服务注册发现?
答:我理解的是主要三块大功能,分别是服务注册 、服务发现、服务状态监控 。
我们当时项目采用的eureka作为注册中心,这个也是spring cloud体系中的一 个核心组件 。
服务注册:服务提供者需要把自己的信息注册到eureka,由eureka来保存这 些信息,比如服务名称、ip、端口等等 。
服务发现:消费者向eureka拉取服务列表信息,如果服务提供者有集群,则消费者会利用负载均衡算法,选择一个发起调用。
服务监控:服务提供者会每隔30秒向eureka发送心跳,报告健康状态,如果 eureka服务90秒没接收到心跳,从eureka中剔除。
原理详解:
3.你能说下nacos与eureka的区别?
答:我们当时xx项目就是采用的nacos作为注册中心,选择nacos还要一个重要原因,就是它支持配置中心,不过nacos作为注册中心,也比eureka要方便好用 一些,主要相同不同点在于几点:
共同点:Nacos与eureka都支持服务注册和服务拉取,都支持服务提供者心跳方式做健康检测。 Nacos与Eureka的区别:
①Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式 。
②临时实例心跳不正常会被剔除,非临时实例则不会被剔除。
③Nacos支持服务列表变更的消息推送模式,服务列表更新更及时。
④Nacos集群默认采用AP(高可用)方式,当集群中存在非临时实例时,采用CP(强一致)模式; Eureka采用AP方式。
原理详解:
4.你们项目负载均衡如何实现的 ?
答:在服务调用过程中的负载均衡一般使用SpringCloud的Ribbon 组件实现 , Feign的底层已经自动集成了Ribbon , 使用起来非常简单,当发起远程调用时,ribbon先从注册中心拉取服务地址列表,然后按照一定的路由策略选择一个发起远程调用,一般的调用策略是轮询。
5.Ribbon负载均衡策略有哪些?
答:
RoundRobinRule:简单轮询服务列表来选择服务器
WeightedResponseTimeRule:按照权重来选择服务器,响应时间越长,权重越小
RandomRule:随机选择一个可用的服务器
ZoneAvoidanceRule:区域敏感策略,以区域可用的服务器为基础进行服务器的选 择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。 而后再对Zone内的多个服务做轮询(默认)。
原理详解:Ribbon负载均衡的流程:
6.如果想自定义负载均衡策略如何实现 ?
答:提供了两种方式:
1,创建类实现IRule接口,可以指定负载均衡策略,这个是全局的,对所有的远程调用都起作用。(全局)
2,在客户端的配置文件中,可以配置某一个服务调用的负载均衡策略,只 是对配置的这个服务生效远程调用。(局部)
如图:
7.什么是服务雪崩,怎么解决这个问题?
答:服务雪崩是指一个服务失败,导致整条链路的服务都失败的情形,一般我们在项目解决的话就是两种方案,第一个是服务降级,第二个是服务熔断。
如果流量太大的话,可以考虑限流。(限流只能预防,不能解决。熔断降级才能解决。)
服务降级:服务自我保护的一种方式,或者保护下游服务的一种方式,用于确保服务不会受请求突增影响变得不可用,确保服务不会崩溃,一般在实际开发中与feign接口整合,编写降级逻辑。
服务熔断:默认关闭,需要手动打开,如果检测到 10 秒内请求的失败率超过 50%,就触发熔断机制。之后每隔 5 秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制。如果微服务可达,则关闭熔断机制,恢复正常请求。
原理详解:
服务降级的逻辑其实很简单,有时候只需要提示一句话就可以,比如:
具体的代码如下,我们一般都是在feign接口发起远程调用的时候进行降级的:
8.你们的微服务是怎么监控的?
答:我们项目中采用的skywalking进行监控的。
1,skywalking主要可以监控接口、服务、物理实例的一些状态。特别是在压测的时候可以看到众多服务中哪些服务和接口比较慢,我们可以针对性的分析和优化。
2,我们还在skywalking设置了告警规则,特别是在项目上线以后,如果报错,我们分别设置了可以给相关负责人发短信和发邮件,第一时间知道项目 的bug情况,第一时间修复。
9.你们项目中有没有做过限流 ? 怎么做的 ?
答:我当时做的xx项目,采用就是微服务的架构,因为xx因为,应该会有突发流量,最大QPS可以达到2000,但是服务支撑不住,我们项目都通过压测最多 可以支撑1200QPS。因为我们平时的QPS也就不到100,为了解决这些突发流量,所以采用了限流。
例如:我们当时有一个活动,到了假期就会抢优惠券,QPS最高可以达到2000,平时10-50之间,为了应对突发流量,需要做限流。
常规限流,为了防止恶意攻击,保护系统正常运行,我们当时系统能够承受最大的QPS是1000。
【第一种方案:Nginx限流】
我们当时采用的nginx限流操作,nginx使用的漏桶算法来实现过滤,让请求 以固定的速率处理请求,可以应对突发流量,我们控制的速率是按照ip进行 限流,限制的流量是每秒20。
【第二种方案:网关限流】
我们当时采用的是spring cloud gateway中支持局部过滤器 RequestRateLimiter来做限流,使用的是令牌桶算法,可以根据ip或路径进 行限流,可以设置每秒填充平均速率,和令牌桶总容量。
原理详解:
首先为什么要限流呢?
——1.是并发量大,为了应对突发流量。2是防止用户恶意刷接口。
限流的实现方式:
(1)Tomcat:可以设置最大连接数【单体项目可以采用】
(2)Nginx
Nginx限流方式一:控制速率(突发流量)漏桶算法:
* 语法:limit_req_zone key zone rate
*key:定义限流对象,binary_remote_addr 就是一种key,基于客户端ip限流。
* Zone:定义共享存储区来存储访问信息,10m可以存储16w ip地址访问信息。
* Rate:最大访问速率,rate=10r/s 表示每秒最多10个请求。
* burst = 20:相当于桶的大小。
* Nodelay:快速处理。
Nginx限流方式一:控制并发连接数:
* limit_conn perip 20: 对应的key是$binary_remote_addr,表示限制单个IP同时最多能持有20个链接。
* limit_conn perserver 100: 对应的key是$server_name,表示虚拟主机(Server)同时能处理并发连接的总数。
这两种Nginx限流方式都比较常见,两者也可以结合着使用。
(3) 网关:令牌桶算法。
yml配置文件中,微服务路由设置添加局部过滤器RequestRateLimiter。
如图:
令牌桶算法:
* key-resolver:定义限流对象(ip、路径、参数),需要代码实现,使用spel表示式获取
* replenishRahe:令牌桶每秒填充平均速率。
* urstCapacity:令牌桶总容量。
令牌桶算法和漏桶算法的区别:漏桶和令牌桶都可以处理突发流量,其中漏桶可以做到绝对 的平滑,令牌桶有可能会产生突发大量请求的情况,一般nginx限流采用的 漏桶,spring cloud gateway中可以支持令牌桶算法。
(4)自定义拦截器。
10.什么是CAP理论?
答:CAP主要是在分布式项目下的一个理论。包含了三项,一致性、可用性、分区容错性。
一致性(Consistency)是指更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致(强一致性),不能存在中间状态。
可用性(Availability) 是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。
分区容错性(Partition tolerance) 是指分布式系统在遇到任何网络分区故障时,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。
11.为什么分布式系统中无法同时保证一致性和可用性?
答:首先一个前提,对于分布式系统而言,分区容错性是一个最基本的要求,因此基本上我们在设计分布式系统的时候只能从一致性(C)和可用性(A)之 间进行取舍。
如果保证了一致性(C):对于节点N1和N2,当往N1里写数据时,N2上的操作必须被暂停,只有当N1同步数据到N2时才能对N2进行读写请求,在N2被暂停操作期间客户端提交的请求会收到失败或超时。显然,这与可用性是相悖的。
如果保证了可用性(A):那就不能暂停N2的读写操作,但同时N1在写数据的话,这就违背了一致性的要求。
12.什么是BASE理论?
答:这个也是CAP分布式系统设计理论 ,BASE是CAP理论中AP方案的延伸,核心思想是即使无法做到强一致性 (StrongConsistency,CAP的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。它的思想包含三方面:
1、Basically Available(基本可用):基本可用是指分布式系统在出现不可预知的故障的时候,允许损失部分可用性,但不等于系统不可用。
2、Soft state(软状态):即是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。 3、Eventually consistent(最终一致性):强调系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。其本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
13.你们采用哪种分布式事务解决方案?
答:我们当时是xx项目,主要使用到的seata的at模式解决的分布式事务。
seata的AT模型分为两个阶段:
1、阶段一RM的工作:① 注册分支事务 ② 记录undo-log(数据快照)③ 执行业务sql并提交 ④报告事务状态
2、阶段二提交时RM的工作:删除undo-log即可
3、阶段二回滚时RM的工作:根据undo-log恢复数据到更新前at模式,牺牲了一致性,保证了可用性,不过,它保证的是最终一致性。
原理详解:
分布式事务的解决方案有两种:1.Seata框架。2.MQ。
(1)Seata事务管理汇中有三个重要的角色:
* TC(Transaction Coordinator)- 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
*TM(Transaction Manager)- 事务管理器:定义全局事务的范围,开始全局事务,提交或回滚全局事务。
* RM(Resource Manager)- 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
Seata的XA模式:
RM一阶段的工作:
① 注册分支事务到TC
② 执行分支业务sql但不提交
③ 报告执行状态到TC
TC二阶段的工作:
* TC检测各分支事务执行状态
a. 如果都成功,通知所有的RM提交事务。
b.如果有失败,通知所有RM回滚事务。
RM二阶段的工作:
* 接收TC指令,提交或回滚事务。
如图:
XA模式属于cap理论中cp,保证了事务的强一致性。它是最后统一提交或回滚的,它的各个分支事务之间要互相等待。
Seata的AT模式:
AT模式同样是分阶段提交的事务模型,不过弥补了XA模型中资源锁定周期过长的缺陷。
阶段一RM的工作:
① 注册分支事务
② 记录undo-log(数据快照)
③ 执行业务sql并提交
④ 报告事务状态
阶段二提交时RM的工作:
* 删除undo-log即可。
阶段二回滚时RM的工作:
* 根据undo-log恢复数据到更新前。
如图:
AT模式是cap理论中的ap,各个分支事务之间不需要互相等待,保证了高可用。
TCC模式的原理:
1.Try:资源的检测和预留;
2.Confirm:完成资操作业务,要求Try成功Confirm 一定要能成功。
3.Cancel: 预留资源释放,可以理解为Try的反向操作。
TCC模式也是cap理论中的ap,性能也是挺高的,不过Try,Confirm,Cancel都需要代码的方式去完成,代码耦合度较高。而XA和AT模式,是seata框架自动完成的。
(2)MQ方式:异步方式,性能相对来说比较高,但是实时性是最差的,如果对数据的强一致性没那么高,可以采用这种方式。
这几种模式的区别和适用的业务:
1.seata的XA模式:cp,需要互相等待各个分支事务的提交,可以保证强一致性,性能差。银行业务
2.seata的AT模式:ap,底层使用undo log实现,性能较好。互联网业务
3.seata的TCC模式:ap,性能较好,不过需要人工编码实现。银行业务
4.MQ模式:在A服务写数据的时候,需要在同一个事务内发送消息到另外一个事务,异步,性能最好。互联网业务
14.分布式服务的接口幂等性如何设计?
答: 嗯,我们当时有一个xx项目的下单操作,采用的token+redis实现的,流程是这样的:
第一次请求,也就是用户打开了商品详情页面,我们会发起一个请求,在后台生成一个唯一token存入redis,key就是用户的id,value就是这个token, 同时把这个token返回前端 。
第二次请求,当用户点击了下单操作后,会携带之前的token,后台先到redis进行验证,如果存在token,可以执行业务,同时删除token;如果不存在,则直接返回,不处理业务,就保证了同一个token只处理一次业务,就 保证了幂等性。
原理详解:
首先,什么是接口幂等性?
——幂等性是指多次调用方法或者接口不会改变业务的状态,可以保证重复调用的结果和单次调用的结果一致。
需要幂等的场景:
① 用户重复点击(网络波动)
② MQ消息重复
③ 应用使用失败或者超时重试机制
而接口幂等:
基于RESTful API的角度对部分常见类型请求的幂等性特点进行分析
解决幂等性问题的方案:
①数据库唯一索引 :可以解决新增问题,但是需要数据库有索引。
②token+Redis : 可以解决新增和修改。性能较好。
③分布式锁 :可以解决新增和修改。但是性能比较低。
15. Xxl-Job的路由策略有哪些?
16. xxl-job任务执行失败怎么解决?
答:有这么几个操作
第一:路由策略选择故障转移,优先使用健康的实例来执行任务 。
第二,如果还有失败的,我们在创建任务时,可以设置重试次数。
第三,如果还有失败的,就可以查看日志或者配置邮件告警来通知相关负责人解决。
17. 如果有大数据量的任务同时都需要执行,怎么解决?
答:我们会让部署多个实例,共同去执行这些批量的任务,其中任务的路由策略是分片广播 ,在任务执行的代码中可以获取分片总数和当前分片,按照取模的方式分摊到各个实例执行就可以了。
代码如下:
只需要拿到分片参数就可以了
* index:当前分片序号(从0开始),执行器集群列表中当前执行器的序号;
* total:总分片数,执行器集群的总机器数量。