面试-微服务篇

时间:2024-07-06 17:49:36

springcloud组件有哪些?

eureka、ribbon负载均衡、feign、hystrix、zuul/gateway网关

nacos、ribbon、feign、sentinel、gateway

服务注册和发现是什么意思?springcloud如何实现服务注册发现?

微服务中必须要使用的组件,考察我们使用微服务的程度

注册中心的核心作用是:服务注册和发现

常见的注册中心:eureka、nacos、zookeeper

参考回答:

我们当时项目采用的eureka作为注册中心,这个是Spring cloud体系中的一个核心组件。

服务注册:服务提供者需要把自己的信息注册到eureka,由eureka来保存这些信息,比如服务名称、IP、端口等等

服务发现:消费者向eureka拉取服务列表信息,如果服务提供者有集群,则消费者会利用负载均衡算法,选择一个发起调用

服务监控:服务提供者会每隔30秒向eureka发送心跳,报告健康状态,如果eureka服务90秒没接收到心跳,从eureka中剔除

nacos和eureka区别

Nacos与eureka的共同点(注册中心)

  1. 都支持服务注册和服务拉取
  2. 都支持服务提供者心跳方式做健康检测

Nacos与Eureka的区别(注册中心)

  1. Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
  2. 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
  3. Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
  4. Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式

Nacos还支持了配置中心,eureka则只有注册中心,也是选择使用nacos的一个重要原因

你们项目负载均衡如何实现的?

负载均衡ribbon,发起远程调用feign就会使用ribbon

回答:微服务的负载均衡主要使用了一个组件ribbon,比如,我们在使用feign远程调用的过程中,底层的负载均衡就是使用了ribbon

ribbon负载均衡策略有哪些?

1.roundRobinRule:简单轮询服务列表来选择服务器

2.weightedResponseTimeRule:按照权重来选择服务器,响应时间越长,权重越小

3. RandomRule:随机选择一个可用的服务器

4.BestAvailableRule:忽略那些短路的服务器,并选择并发数较低的服务器

5.RetryRule:重试机制的选择逻辑

6.AvailabilityFilteringRule:可用性敏感策略,先过滤非健康的,再选择连接数较小的实例

7.ZoneAvoidanceRule:以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询(默认)

如果想自定义负载均衡策略如何实现?

可以自己创建类实现IRule接口 , 然后再通过配置类或者配置文件配置即可 ,通过定义IRule实现可以修改负载均衡规则,提供了两种方式:

  1. 创建类实现rule接口,可以指定负载均衡策略(全局)
  2. 在客户端的配置文件中,可以配置某一个服务调用的负载均衡策略(局部)

解决过哪些复杂的问题?什么是服务雪崩?怎么解决这个问题的?

什么是服务雪崩?熔断降级(解决)限流(预防)

服务雪崩:一个服务失败,导致整条链路的服务都失败的情况

服务降级:服务自我保护的一种方式,或者保护下游服务的一种方式,用于确保服务不会受请求突增影响变得不可用,确保服务不会崩溃。

服务熔断:hystrix熔断机制,用于监控微服务调用情况,默认是关闭的,如果需要开启需要在引导类上添加注解@EnableCircuitBreaker

如果检测到 10 秒内请求的失败率超过 50%,就触发熔断机制。之后每隔 5 秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制。如果微服务可达,则关闭熔断机制,恢复正常请求

参考回答:

服务雪崩:一个服务失败,导致整条链路的服务都失败的情形

服务降级:服务自我保护的一种方式,或者保护下游服务的一种方式,用于确保服务不会受请求突增影响变得不可用,确保服务不会崩溃,一般在实际开发中与feign接口整合,编写降级逻辑

服务熔断:默认关闭,需要手动打开,如果检测到 10 秒内请求的失败率超过 50%,就触发熔断机制。之后每隔 5 秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制。如果微服务可达,则关闭熔断机制,恢复正常请求

你们微服务是怎么监控的?

你们项目中有没有做过限流?怎么做的?

为什么要限流?

并发量大(突发流量)

防止用户恶意刷接口

限流的实现方式:

tomcat:可以设置最大连接数

nginx:漏桶算法

网关:令牌桶算法

自定义拦截器

nginx限流

控制速率(突发流量)

语法:limit_req_zone key zone rate

key:定义限流对象,binary_remote_addr就是一种key,基于客户端ip限流

Zone:定义共享存储区来存储访问信息,10m可以存储16wip地址访问信息

Rate:最大访问速率,rate=10r/s  表示每秒最多请求10个请求

burst=20:相当于桶的大小

Nodelay:快速处理

控制并发连接数

limit_conn perip 20:对应的key是 $binary_remote_addr,表示限制单个IP同时最多能持有20个连接。

limit_conn perserver 100:对应的key是 $server_name,表示虚拟主机(server) 同时能处理并发连接的总数。

网关限流

yml配置文件中,微服务路由设置添加局部过滤器RequestRateLimiter

key-resolver :定义限流对象( ip 、路径、参数),需代码实现,使用spel表达式获取

replenishRate :令牌桶每秒填充平均速率。

urstCapacity :令牌桶总容量。

参考回答:

1,先来介绍业务,什么情况下去做限流,需要说明QPS具体多少

我们当时有一个活动,到了假期就会抢购优惠券,QPS最高可以达到2000,平时10-50之间,为了应对突发流量,需要做限流

常规限流,为了防止恶意攻击,保护系统正常运行,我们当时系统能够承受最大的QPS是多少(压测结果)

2,nginx限流

控制速率(突发流量),使用的漏桶算法来实现过滤,让请求以固定的速率处理请求,可以应对突发流量

控制并发数,限制单个ip的链接数和并发链接的总数

3,网关限流

在spring cloud gateway中支持局部过滤器RequestRateLimiter来做限流,使用的是令牌桶算法

可以根据ip或路径进行限流,可以设置每秒填充平均速率,和令牌桶总容量

限流常见的算法有哪些?

解释一下CAP和BASE

CAP定理

1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标:

Consistency(一致性)

Availability(可用性)

Partition tolerance (分区容错性)

Eric Brewer 说,分布式系统无法同时满足这三个指标。

这个结论就叫做 CAP 定理。

Consistency(一致性):用户访问分布式系统中的任意节点,得到的数据必须一致

Availability(可用性):用户访问集群中的任意健康节点,得到的数据必须一致

Partition(分区):因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区。

Tolerance(容错):在集群出现分区时,整个系统也要持续对外提供服务

结论:

  • 分布式系统节点之间肯定是需要网络连接的,分区(P)是必然存在的
  • 如果保证访问的高可用性(A),可以持续对外提供服务,但不能保证数据的强一致性-->  AP
  • 如果保证访问的数据强一致性(C),就要放弃高可用性   --> CP

BASE理论

BASE理论是对CAP的一种解决思路,包含三个思想:

Basically Available (基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。

Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。

Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。

参考回答:

CAP定理(一致性、可用性、分区容错性)

1、分布式系统节点通过网络连接,一定会出现分区问题(P)

2、当分区出现时,系统的一致性(C)和可用性(A)就无法同时满足

BASE理论

1、基本可用

2、软状态

3、最终一致

解决分布式事务的思想和模型:

1、最终一致思想:各分支事务分别执行并提交,如果有不一致的情况,再想办法恢复数据(AP)

2、强一致思想:各分支事务执行完业务不要提交,等待彼此结果。而后统一提交或回滚(CP)

你们采用哪种分布式事务解决方案?

Seata事务管理中有三个重要的角色:

  • TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
  • TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

分布式服务的接口幂等性如何设计?

幂等: 多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致。

需要幂等场景

用户重复点击(网络波动)

mq消息重复

应用使用失败或超时重试机制

接口幂等

基于RESTful API的角度对部分常见类型请求的幂等性特点进行分析

请求方式

说明

GET

查询操作,天然幂等

POST

新增操作,请求一次与请求多次造成的结果不同,不是幂等的

PUT

更新操作,如果是以绝对值更新,则是幂等的。如果是通过增量的方式更新,则不是幂等的

DELETE

删除操作,根据唯一值删除,是幂等的

解决幂等:数据库唯一索引(新增)、token+redis(新增、修改)、分布式锁(新增、修改)

Token+redis方式

创建商品、提交订单、转账、支付等操作

分布式锁

参考回答:

  1. 幂等: 多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致
  2. 如果是新增数据,可以使用数据库的唯一索引
  3. 如果是新增或修改数据
    • 分布式锁,性能较低
    • 使用token+redis来实现,性能较好

第一次请求,生成一个唯一token存入redis,返回给前端

第二次请求,业务处理,携带之前的token,到redis进行验证,如果存在,可以执行业务,删除token;如果不存在,则直接返回,不处理业务

你们项目中使用了什么分布式任务调度

Xxl-job解决的问题

解决集群任务的重复执行问题

cron表达式定义灵活

定时任务失败了,重试和统计

任务重大,分片执行

Xxl-job路由策略有哪些?

FIRST(第一个):固定选择第一个机器;

LAST(最后一个):固定选择最后一个机器;

ROUND(轮询)

RANDOM(随机):随机选择在线的机器;

CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。

LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;

LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;

FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;

BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;

SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;

回答:xxl-job提供了很多的路由策略,我们平时用的较多就是:轮询、故障转移、分片广播…

Xxl-job任务执行失败怎么解决?

故障转移+失败重试次数,查看日志分析---->邮件告警

回答:

路由策略选择故障转移,使用健康的实例来执行任务

设置重试次数

查看日志+邮件告警来通知相关负责人解决

如果有大数据量的任务同时都需要执行,怎么解决?

执行器集群部署时,任务路由策略选择分片广播情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务

分片参数

index:当前分片序号(从0开始),执行器集群列表中当前执行器的序号;

total:总分片数,执行器集群的总机器数量;

回答:

让多个实例一块去执行(部署集群),路由策略分片广播

在任务执行的代码中可以获取分片总数和当前分片,按照取模的方式分摊到各个实例执行