Java大厂面试题——第四章之微服务篇
文章目录
课程地址
一、Spring cloud
1. 服务注册
1.1 Spring cloud 5大组件有哪些?
- 基础的内容考察
- 回答原则:简单的问题
不能答错

- Eureka:注册中心
- Ribbon:负载均衡
- Feign:远程调用
- Hystrix:服务熔断
- Zuul/Gateway:网关
随着SpringCloudAlibaba在国内兴起,我们项目中使用了一些阿里巴巴的组件 - 注册中心/配置中心 Nacos
- 负载均衡 Ribbon
- 服务调用 Feign
- 服务保护 sentinel
- 服务网关 Gateway
1.2 eureka
1.3.1 服务注册和发现是什么意思?Spring Cloud如何实现服务注册发现?
- 微服务中必须要使用的组件,考察我们使用微服务的程度
- 注册中心的核心作用是:服务注册和发现
- 常见的注册中心:
eureka、nacos、zookeeper
Eureka的作用:

1.3 nacos
1.3.1 我看你之前也用过nacos、你能说下nacos与eureka的区别?

spring:
cloud:
nacos:
discovery:
server-addr:192.168.200.130:8848
ephemeral:false #设置为非临时实例
默认是临时实例,和eureka一样,但是如果设置成false,就是注册中心主动向服务提供者询问
回答:
- nacos与eureka的共同点(注册中心)
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
- nacos与eureka的区别(注册中心)
- nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会剔除
- nacos支持服务列表变更的消息推送模式,服务列表更新更及时
- nacos集群默认采用AP
高可用方式,当集群中存在非临时实例时,采用CP强一致模式;eureka采用AP方式
- nacos还支持了配置中心,eureka则只有注册中心,也是选择使用nacos的一个重要原因
2. 负载均衡
2.1 Ribbon负载均衡策略
2.1.1 你们项目负载均衡如何实现的?
- 负载均衡Ribbon,发起远程调用feign就会使用Ribbon
- Ribbon负载均衡策略有哪些?
- 如果想要自定义负载均衡策略如何实现?

2.1.2 Ribbon负载均衡策略有哪些?
RoundRobinRule:简单轮询服务列表来选择服务器WeightedResponseTimeRule:按照权重来选择服务器,响应时间越长,权重越小RandomRule:随机选择一个可用的服务器- BestAvailableRule:忽略那些短路的服务器,并选择并发数较低的服务器
- RetryRule:重试机制的选择逻辑
- AvailabilityFilteringRule:可用性敏感策略,先过滤非健康的,在选择连接数较小的实例
ZoneAvoidanceRule:以区域可用的服务器为基础进行服务器的选择,使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等,而后再对Zone内的多个服务做轮询
2.2 自定义负载均衡
可以自己创建类实现IRule接口,然后再通过配置类或者配置文件配置即可,通过定义IRule实现可以修改负载均衡规则,有两种方式:

3. 熔断、降级
3.1 什么是服务雪崩,怎么解决这个问题?
- 什么是服务雪崩?

雪崩:一个服务失败,导致整条链路的服务都失败的情形
- 熔断降级(解决)
Hystrix服务熔断降级- 服务降级
针对某一个接口
服务降级是服务自我保护的一种方式,或者保护下游服务的一种方式,用于确保服务不会受请求突增影响变得不可用,确保服务不会崩溃
- 服务降级

代码实现如下:

如果降级太多,则会触发熔断机制
2. 服务熔断针对于整个服务
Hystrix熔断机制,用于监控微服务服务调用情况,默认是关闭的,如果需要开启需要在引导类上添加注解:
@EnableCircuitBreaker如果监测到10秒内请求的失败率超过50%,就会触发熔断机制。之后每隔5秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制。如果微服务可达,则关闭熔断机制,恢复正常请求

- 限流(预防)
详见下面的第二点
4. 监控
4.1 skywalking
4.1.1 你们的微服务是怎么监控的?

为什么需要监控?
- 问题定位
- 性能分析
- 服务关系
- 服务告警
几种监控工具 - Springboot-admin
- prometheus+Grafana
- zipkin
- skywalking
一个分布式系统的应用程序性能监控工具(ApplicationPerformanceManagment),提供了完善的链路追踪能力,apache的顶级项目(前华为产品经理吴晟主导开源)

二、业务相关
1. 限流
1.1 你们项目中有没有做过限流?怎么做的?
为什么要限流?
1,并发的确大(突发流量)
2,防止用户恶意刷接口
限流的实现方式:
- tomcat:可以设置最大连接数
maxThreads单体项目
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" maxThreads="150" redirectPort="8443" />
- Nginx:漏桶算法
- 网关:令牌桶算法
- 自定义拦截器
1.2 漏桶算法

- 控制速率(突发流量)
http{
limit_req_zone $binary_remote_addr zone=servicelRateLimit:10m rate=10r/s
server {
listen 80;
server_name localhost;
location / {
limit_req_zone = servicelRateLimit burst=20 nodelay;
proxy_pass http://targetserver;
}
}
}
- 语法:limit_req_zone key zone rate
- key:定义限流对象,binary_remote_addr就是一种key,基于客户端ip限流
- Zone:定义共享存储区来存储访问信息,10m可以存储16wip地址访问信息
- Rate:最大访问速率,rate=10r/s 表示每秒最多请求10个请求
- burst=20:相当于桶的大小
- Nodelay:快速处理
- 控制最大连接数
http{
limit_req_zone $binary_remote_addr zone=perip:10m;
limit_req_zone $server_name zone=perserver:10m;
server {
listen 80;
server_name localhost;
location / {
...
limit_conn perip 20;
limit_conn perserver 100;
proxy_pass http://targetserver;
}
}
}
- limit_conn perip 20:对应的key是$binary_remote_addr,表示限制单个IP同时最多能持有20个连接
- limit_conn perserver 100:对应的key是$server_name,表示虚拟机(server)同时能处理并发连接的总数
1.3 令牌桶算法

网关限流
yml配置文件中,微服务路由设置添加局部过滤器RequestRateLimiter
- id: gateway-consumer
uri: lb://GATEWAY-CONSUMER
predicates:
- Path=/order/**
filters:
- name:RequestRateLimiter
args:
# 使用SpEL从容器中获取对象
key-resolver: '#{@pathKeyResolver}'
# 令牌桶每秒填充平均速率
redis-rate-limiter.replenishRate:1
# 令牌桶的上限
redis-rate-limiter,burstCapacity:3
- key-resolver:定义限流对象(ip、路径、参数),需代码实现,使用spel表达式获取
- replenishRate:令牌桶每秒填充平均速率
- urstCapacity:令牌桶总容量
2. 分布式事务
2.1 分布式理论CAP、BASE
- 分布式事务方案的指导
- 分布式系统设计方向
- 根据业务指导使用正确的技术选择
CAP定理
1998年,加州大学的计算机科学家Eric Brewer提出,分布式系统有三个指标:
- Consistency(一致性):用户访问分布式系统中的任意节点,得到的数据必须一致

- Availability(可用性):用户访问集群中的任意健康节点,必须能得到响应,而不是超时或拒绝

- Partition tolerance(分区容错性):
- Partition(分区):因为网络故障或其他原因导致分布式系统中的部分节点与其他节点失去连接,形成独立分区
- tolerance(容错):在集群出现分区时,整个系统也要持续对外提供服务

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

Eric Brewer说,分布式系统无法同时满足这三个指标
这个结论就叫做CAP定理
BASE理论
BASE理论是对CAP的一种解决思路,包含三个思想: BasicallyAvailable(基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用Soft State(软状态):在一定时间内,允许出现中间装填,比如临时的不一致状态Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致
解决分布式事务的思想和模型:
1,最终一致思想:各分支事务分别执行并提交,如果有不一致的情况,再想办法恢复数据(AP)
2,强一致思想:各分支事务执行完业务不要提交,等待彼此结果。而后统一提交或回滚(CP)
2.2 分布式事务解决方案
简历上写的是微服务项目
- Seata框架(XA、AT、TCC)
详见2.3 - MQ
互联网业务

异步的,性能比较高,实时性比较差
2.3 seata
Seata事务管理中有三个重要的角色
- TC(Transaction Coordinator)-事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚
- TM(Transaction Manager)-事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务
- RM(Resource Manager)-资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

XA模式银行业务
RM一阶段的工作:
1> 注册分支事务到TC
2> 执行分支业务sql但不提交
3> 报告执行状态到TC
TC二阶段的工作:
TC检测各分支事务执行状态
a. 如果都成功,通知所有RM提交事务
b. 如果都失败,通知所有RM回滚事务
RM二阶段的工作:
接收TC指令,提交或回滚事务

倾向CP定理AT模式互联网业务
AT模式同样是分阶段提交的事务模型,不过弥补了XA模型中资源锁定周期过长的缺陷
阶段一RM的工作:
- 注册分支事务
记录undo-log(数据快照)- 执行业务sql
并提交 - 报告事务状态
阶段二提交时RM的工作 - 删除undo-log即可
阶段二回滚时RM的工作 - 根据undo-log恢复数据到更新前

采用AP,推荐模式
TCC模式银行业务
1、Try:资源的检测和预留
2、Confirm:完成资源操作业务;要求Try成功Confirm一定成功
3、Cancel:预留资源释放,可以理解为try的反向操作

AP模式,代码完成,前面的框架自动完成
3. 分布式服务接口幂等
3.1 分布式服务的接口幂等性如何设计?
幂等:多次调用方法或接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致
需要幂等场景
- 用户重复点击(网络波动)
- MQ消息重复
- 应用使用失败或超时重试机制
基于RESTful API的角度对部分常见类型请求的幂等性特点进行分析
| 请求方式 | 说明 |
|---|---|
| GET | 查询操作,天然幂等 |
| POST | 新增操作,请求一次与请求多次造成的结果不同,不是幂等的 |
| PUT | 更新操作,如果是以绝对值更新,则是幂等的。如果是通过增量的方式更新,则不是幂等的 |
| DELETE | 删除操作,根据唯一值删除,是幂等的 |
update t_item set money = 500 where id = 1; √
update t_item set money = money + 500 where id = 1;×
解决方案:
- 数据库唯一索引
新增 - token+redis
新增、修改
创建商品、提交订单、转账、支付等操作

- 分布式锁
新增、修改

- 快速失败(抢不到锁的线程)
- 控制锁的粒度,越小越好
4. 分布式任务调度
4.1 xxl-job
4.1.1 你们项目中使用了什么分布式任务调度?
xxl-job
首先,还是要描述当时是什么场景用了任务调度
xxl-job解决的问题
- 解决集群任务的重复执行问题
- corn表达式定义灵活
- 定时任务失败了,重试和统计
- 任务量大,分片执行
4.1.2 xxl-job路由策略有哪些?
任务找机器执行的策略
- FIRST(第一个):固定选择第一个机器
- LAST(最后一个):固定选择最后一个机器
ROUND(轮询)- RANDOM(随机):随机选择在线的机器
- CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上
- LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举
- LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举
FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度- BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度
SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;
4.1.3 xxl-job任务执行失败怎么解决?
故障转移+失败重试,查看日志分析---->邮件告警
4.1.4 如果有大数据量的任务同时都需要执行,怎么解决?
执行器集群部署时,任务路由策略选择分片广播情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务

分片参数
- index:当前分片序号(从0开始),执行器集群列表中当前执行器的序号;
- total:总分片数,执行器集群的总机器数量

更多推荐
所有评论(0)