黑马面试专题-微服务
框架

SpringCloud 5大组件有哪些
通常情况下:
- 注册中心 Nacos
- 负载均衡 Ribbon
- 服务调用 Feign
- 服务保护/服务熔断 sentinel
- 服务网关 GateWay
服务注册和发现是什么意思?SpringCloud 如何实现服务注册?
Eureka的作用

回答:
我们当时项目使用Eureka作为注册中心,这也是spring cloud体系中一个核心组件
**服务注册:**服务提供者需要把自己的信息注册到eureka,有eureka来保存信息,比如服务名称、ip、端口号
**服务发现:**服务的消费者向eureka拉去服务列表信息,如果服务提供者有集群,消费者会利用负载均衡的算法,选择一个发起调用
**服务监控:**服务提供者每隔30s向eureka发送心跳,报告健康状态,如果eureka服务90s没有接受心跳,从eureka服务中删除
我看你之前也用过nacos,你能说一下nacos和eureka的区别吗
nacos

回答:
- Nacos和eureka共同点:
- 都支持注册服务和服务拉去
- 都支持服务提供者发送心跳检测
- Nacos和eureka的区别
- Nacos支持服务端主动检测提供者状态:临时实例采用心跳检测,非临时实例采用主动检测模式
- 临时实例心跳不正常会被移除,非临时实例则不会移除
- Nacos支持的服务列表变更的消息推送模式,服务列表更新更及时
- Nacos集群默认采用的AP模式(高可用),当集群中存在非临时实例采用CP模式(强一致性);Eureka采用AP模式
- Nacos还支持配置中心,eureka只有注册中心
你们项目中负载均衡如何实现?
Ribbon负载均衡的流程

Ribbon负载均衡的策略?
- RoundRobinRule:简单轮询服务列表来选择服务器
- WeightedResponseTimeRule:按照权重来选择服务器,响应时间越长,权重越小
- RandomRule:随机选择一个可用的服务器
- BestAvailableRule:忽略那些短路的服务器,并选择并发数较低的服务器
- RetryRule:重试机制的选择逻辑
- AvailabilityFiltering Rule:可用性敏感策略,先过滤非健康的,再选择连接数较小的实例
- ZoneAvoidanceRule:以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这 个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询(默认)
如果想自定义负载均衡策略如何实现?
两种方式:
- 创建类实现IRule接口,可以指定负载均衡策略(全局)
- 在客户端的配置文件中,可以配置一个服务调用的负载均衡策略(局部)
什么是服务雪崩,这么解决这个问题?

回答:
- 服务雪崩:一个服务失败,导致整条链路的服务都失败的情形
- 服务降级:服务自我保护的一种方式,或者保护下有服务的一种方式,用于确保服务不会受请求突增一ing想变得不可用,确保服务不会崩溃,一般在实际开发与feign接口整合,编写降级逻辑
- 服务熔断:默认关闭。需手动打开,如果监测到10s内请i去失败率炒超过50%,就出发熔断机制。之后没过5s,重新发送请求微服务,如果微服务不能响应,继续熔断。如果微服务有响应,则关闭熔断,恢复正常
你们的微服务是怎么监控

我们项目中采用的skywalking进行监控的
- skywalking主要可以监控接口、服务、物理实例的一些状态。特别是在压测的时候可以看到众多服务中哪些服 务和接口比较慢,我们可以针对性的分析和优化。
- 我们还在skywalking设置了告警规侧,特别是在项目上线以后,如果报错,我们分别设置了可以给相关负责人 发短信和发邮件,第一时间知道项目的bug情况,第一时间修复
你们项目中有没有做过限流?怎么做的?
为什么要限流?
- 并发的确大(突发流量)
- 防止用户恶意刷接口
限流的实现方式:
-
Tomcat:可以设置最大连接数
-
Nginx:漏桶算法
-
网关:令牌桶算法
-
自定义拦截器
Nginx:
原理:就是想象有一个固定大小的桶,这个桶有一个小孔可以漏水。当数据(如网络请求或数据包)到达时,它们会被放入这个桶中。桶按照固定的速率漏水(即处理数据),而不管数据是以什么速率流入的。


**网关限流: **
**令牌桶算法:**固定生成令牌存入令牌桶,桶满后暂停生成,请求需要到令牌桶申请令牌,没有申请到令牌会被阻塞或者丢弃,申请到令牌的请求才会被服务处理

- key-resolver:定义限流对象(ip、路径、参数),需代码实现,使用spel表达式获取
- replenishRate:令牌桶每秒填充平均速率。
- urstCapacity:令牌桶总容量。
回答:
- 先介绍业务,什么情况下去做限流,需要说明QSP具体多少
- 我们当时有一个活动,到了假期就会抢购优惠,QPS最高可以达到2000,平时10-50之间,为了应对突发流量,需要做限流
- 常规限流,为了恶意攻击,保护系统正常运行,我们当时系统能够承载最大的QPS是多少
- nginx限流
- 控制速率(突发流量),使用的漏桶算法来实现过滤,让请求以固定的速率处理请求,可以应对突发流量
- 控制并发数,限制单个ip的连接数和并发连接的总数
- 网管限流
- 在spring cloud gateway中支持局部过滤器RequestRateLimiter来做限流,使用令牌桶算法
- 可以根据id或者路径进行限流,可以设置之每秒填充平均速率,金额令牌总容量
解释一下CAP和BASE
Consistency(一致性)
用户访问分布式系统中的任意节点,得到的数据必须一致

Availability(可用性)
用户访问集群中任意健康节点,必须得到响应,而不是超市或拒绝
Partition tolerance(分区容错)
Partition(分区):与因为网络故障或者其他故障导致分布式系统中的部分节点与其他节点断开连接,形成独立的分区
Tolerance(容错):在集群出现分区时候,整个系统也要持续对外提供服务

解决:如果需要数据的强一致性,等待网络连接成功,数据同步完成之后在访问
结论:
- 分布式系统节点之间需要网络连接,分区(P)是必然存在的
- 如果要保证访问的高可用性(A),可以持续对外提供服务,但不能保证数据的强一致性-->AP
- 如果要保证访问的数据强一致性(C),就要放弃高可用性-->CP
BASE理论
BASE理论是对CAP的一种解决思路,包含三个思想:
- Basically Available(基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
- Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。
- Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。

回答:
- CAP定理(一致性、可用性、分区容错性)
- 分布式系统节点通过网络连接,一定会出现分区问题(P)
- 当分区出现时,系统的一致性(C)和可用性(A)就无法同时满足
- BASE理论
- 基本可用
- 软状态
- 最终一致
- 解决分布式事务的思想和模型:
- 最终一致思想:各分支事务分别执行并提交,如果有不一致的情况,再想办法恢复数据(AP)
- 强一致思想:各分支事务执行完业务不要提交,等待彼此结果。而后统一提交或回滚(CP)
你们项目采用哪种分布式事务解决方案?
简历上写的微服务,只要发生了多个服务之间的写数据,都需要进行分布式事务控制
描述项目中采用的哪种方式(seata|MQ)
- seata的XA模式,CP,需要互相等待各个分之十五提交,可以保证强一致性,性能较差 银行业务
- seata的AT模式。AP。底层使用undo log实现,性能好 互联网业务
- seata的TCC模式,AP,性能较好,不过需要人工编码实现 银行业务
- MQ模式实现分布式事务,在A服务写数据的时候,需要在同一个事务内发送消息到另一个事务,异步,性能最好 互联网业务
分布式服务的接口幂等性如何设计?
幂等:多次调用方法或者接口不会改变业务状态,可以保证重复条用的结果和单词条用的结果一直
需要幂等场景
- 用户重复点击(网络波动)
- MQ消息重复
- 应用使用失败或者超时重复机制
基于RESTful API的角度对部分常见类型请求的幂等性特点进行分析

解决:
-
加唯一索引
-
token+redis

第一次请求(获取token)
- 客户端发起第一次请求:用户在客户端(如手机APP或网页)进行创建商品、提交订单、转账、支付等操作时,首先向服务端发送一个请求。
- 服务端生成唯一token:服务端接收到请求后,生成一个唯一的token,并将这个token存储到Redis中。这个token的作用是作为后续请求的凭证,用于验证请求的合法性。
- 返回token给客户端:服务端将生成的token返回给客户端,客户端需要保存这个token以便在后续的操作中使用。
第二次请求(带token请求业务接口)
- 客户端带token请求业务接口:当用户再次进行相关操作(如提交订单)时,客户端会带上之前获取的token一起发送请求到服务端。
- 服务端验证token是否存在:服务端接收到带有token的请求后,会先检查Redis中是否存在这个token。如果存在,则表示这是一个合法的请求;如果不存在,则认为这是一个非法或重复的请求。
- 处理业务并删除token:如果token存在,服务端会继续处理用户的业务请求(如创建订单),并在处理完成后从Redis中删除这个token,以防止同一个token被多次使用。如果token不存在,服务端则直接返回错误信息,拒绝处理该请求。
- 返回请求结果:无论请求是否成功,服务端都会将处理结果返回给客户端,客户端根据返回的结果进行相应的展示或提示。
通过这种方式,可以有效地防止用户因网络延迟、误操作等原因导致的重复提交问题,保证了业务操作的准确性和系统的稳定性。
- 分布式锁

回答:
- 幂等:多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致
- 如果是新增数据,可以使用数据库的唯一索引
- 如果是新增或修改数据
- 分布式锁,性能较低
- 使用token+redis:来实现,性能较好
- 第一次请求,生成一个唯一token:存入redis,返回给前端
- 第二次请求,业务处理,携带之前的token,到redis进行验证,如果存在,可以执行业务,删除token;如果不存在,则直接返回,不处理业务
你们项目中使用了什么分布式任务调度
xxl-job解决问题
- 解决集群任务的重复执行问题
- cron表达式定义灵活
- 定时任务失败了,充实和统计
- 任务量大,分片执行
路由策略有哪些
xjob提供了很多的路由策略,我们平时用的较多就是:轮询、故障转移、分片广播…
xxl-job任务执行失败怎么解决?
- 路由策略选择敌障转移,使用健康的实例来执行任务
- 设置重试次数
- 查看日志+邮件告警来通知相关负责人解决
如果有大数据量的任务同事都需要执行,这么解决?
- 让多个实例一块去执行(部署集群),路由策略分片广播
- 在任务执行的代码中可以获取分片总数和当前分片,按照取模的方式分摊到各个实例执行
