文章目录
- Spring Cloud
- 1.Spring Cloud 5大组件有哪些?
- 2.服务注册和发现是什么意思?Spring Cloud 如何实现服务注册发现?
- 3.负载均衡如何实现的 ?
- 4.什么是服务雪崩,怎么解决这个问题?
- 5.微服务是怎么监控的
- 业务相关
- 6.项目中有没有做过限流 ? 怎么做的 ?
- 7.解释一下CAP和BASE
- 8.分布式事务解决方案?
- 9.分布式服务的接口幂等性如何设计?
- 10.分布式任务调度
Spring Cloud
1.Spring Cloud 5大组件有哪些?
以下面这幅图为例:
通常情况下可以分为:
Eureka : 注册中心
- Ribbon : 负载均衡
- Feign : 远程调用
Hystrix : 服务熔断
- Zuul/Gateway : 网关
一般现在使用SpringCloudAlibba比较多:
- 注册中心/
配置中心 Nacos
- 负载均衡 Ribbon
- 服务调用 Feign
服务保护 sentinel
- 服务网关 Gateway
2.服务注册和发现是什么意思?Spring Cloud 如何实现服务注册发现?
注册中心的核心作用是:服务注册和发现
而现在常用的注册中心可以分为两种:
Eureka(被动型)
具体流程:
服务注册
:服务提供者需要把自己的信息注册到eureka
,由eureka来保存这些信息,比如服务名称、ip、端口等等服务发现
:消费者向eureka拉取服务列表信息,如果服务提供者有集群,则消费者会利用负载均衡算法
,选择一个发起调用
服务监控
:服务提供者会每隔30秒向eureka发送心跳
,报告健康状态,如果eureka服务90秒没接收到心跳
,从eureka中剔除
nacos(主动型)
具体流程:
具体流程与Eureka类似
Nacos与eureka的共同点(注册中心)
- 都支持
服务注册和服务拉取
- 都支持
服务提供者心跳方式做健康检测
Nacos与Eureka的区别(注册中心)
- Nacos支持服务端主动检测提供者状态:
临时实例采用心跳模式
,非临时实例采用主动检测模式
临时实例心跳不正常会被剔除,非临时实例则不会被剔除 - Nacos支持服务列表变更的
消息推送模式
,服务列表更新
更及时 - Nacos集群默认采用
AP(高可用)
方式,当集群中存在非临时实例时,采用CP(强一致)模式;Eureka采用AP方式 - Nacos还支持了
配置中心
,eureka则只有注册中心,也是选择使用nacos的一个重要原因
3.负载均衡如何实现的 ?
微服务的负载均衡主要使用了一个组件Ribbon
,比如,我们在使用feign远程调用
的过程中,底层的负载均衡
就是使用了ribbon
Ribbon负载均衡策略有哪些 ?
- RoundRobinRule:简单
轮询
服务列表来选择服务器 - WeightedResponseTimeRule:按照
权重
来选择服务器,响应时间
越长,权重越小 - RandomRule(随机):
随机
选择一个可用的服务器 - ZoneAvoidanceRule(
就近原则
):区域敏感策略,以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询(默认)
(如果没有区域的概念,就默认轮询)
自定义负载均衡策略
有两种方式:
- (创建类配置)创建类实现IRule接口,可以指定负载均衡策略(
全局
)
- (配置文件配置单个服务)在客户端的配置文件中,可以配置某一个服务调用的负载均衡策略(
局部
)
4.什么是服务雪崩,怎么解决这个问题?
服务与服务之间是存在互相调用的情况
服务雪崩就是一个服务失败,导致整条链路的服务都失败的情形。
解决办法有两种:
1. 服务降级(服务部分接口)
服务降级是
服务自我保护的一种方式
,或者保护下游服务
的一种方式,用于确保服务不会受请求突增影响变得不可用
,确保服务不会崩溃
一般在实际开发中与feign接口整合
,编写降级逻辑
例如上图,update方法可以正常访问,但是save方法不能访问,这个时候就会走一个服务降级的方案(也就是走另一个方案),给用户一些提示消息
上图通过在服务接口上加上@FeignClient注解
,指定服务的名字
和出现异常后要降级的执行类
如果降级的接口达到一定数量,就会触发熔断机制
2. 熔断机制(整个服务)
默认关闭
,需要手动打开,如果检测到10 秒内请求的失败率超过 50%
,就触发熔断机制。之后每隔5 秒重新尝试请求微服务
,如果微服务不能响应
,继续
走熔断
机制。如果微服务可
达,则关闭
熔断机制,恢复正常请求
5.微服务是怎么监控的
- 1,skywalking主要可以
监控接口、服务、物理实例的一些状态
。特别是在压测
的时候可以看到众多服务中哪些服务和接口比较慢
,我们可以针对性的分析
和优化
。 - 2,我们还在skywalking设置了
告警规则
,特别是在项目上线以后,如果报错,我们分别设置了可以给相关负责人发短信和发邮件
,第一时间知道项目的bug情况
,第一时间修复
业务相关
6.项目中有没有做过限流 ? 怎么做的 ?
为什么要限流?
1,并发的确大(突发流量)
2,防止用户恶意刷接口
限流的实现方式:
- Tomcat:可以设置最大连接数
每一个服务都有一台tomcat服务器,可以在通过Tomcat设置最大连接数,但是这种只适合与单体项目
- Nginx限流:包括两种限流方式
控制速率(突发流量):
核心就是采用了
漏桶算法
做限流
使用的漏桶算法来实现过滤,让请求以固定的速率处理请求,可以应对突发流量
控制并发连接数
限制
单个ip的链接数
和并发链接的总数
3. 网关限流
在spring cloud gateway中支持
局部过滤器RequestRateLimiter
来做限流
,使用的是令牌桶算法
可以根据ip
或路径
进行限流,可以设置每秒令牌填充平均速率
,和令牌桶总容量
漏桶和令牌桶的区别
漏桶:固定速率放行请求;
令牌桶:固定速率生成令牌,请求拿到令牌则放行
,多余令牌则存储;
令牌桶处理的速度可能会超过生成令牌的速度
7.解释一下CAP和BASE
CAP理论
- Consistency(一致性)
用户访问分布式系统中的任意节点,得到的数据必须一致
- Availability(可用性)
用户访问集群中的任意健康节点,必须能得到响应,而不是超时或拒绝
- Partition tolerance (分区容错性)
因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区。在集群出现分区时,整个系统也要持续对外提供服务
结论:
- 分布式系统节点之间肯定是需要网络连接的,
分区(P)
是必然存在的
- 如果保证访问的
高可用性(A)
,可以持续对外提供服务
,但不能保证数据的强一致性
–> AP - 如果
保证访问的数据强一致性
(C),就要放弃高可用性
--> CP
BASE理论
BASE理论是对CAP的一种解决思路,包含三个思想:
- Basically Available (基本可用):分布式系统在出现故障时,
允许损失部分可用性
,即保证核心可用。 - Soft State(软状态):在一定时间内,允许出现
中间状态
,比如临时的不一致状态。 - Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,
最终达到数据一致。
核心在于事务协调器
解决分布式事务的思想和模型:
最终
一致思想:各分支事务分别执行并提交
,如果有不一致的情况
,再想办法恢复数据(AP
)强一致思想
:各分支事务执行完业务不要提交
,等待彼此结果。而后统一提交或回滚(CP)
8.分布式事务解决方案?
Seata框架(XA、AT、TCC)
Seata事务管理中有三个重要的角色:
- TC (Transaction Coordinator) -
事务协调者
:维护全局和分支事务的状态,协调全局事务提交或回滚。 - TM (Transaction Manager) -
事务管理器
:定义全局事务的范围、开始全局事务、提交或回滚全局事务。 - RM (Resource Manager) -
资源管理器
:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
XA模式(CP)
AT模式(AP)
TCC模式(AP)
1、Try:资源的检测和预留;
2、Confirm:完成资源操作业务;要求 Try 成功 Confirm 一定要能成功。
3、Cancel:预留资源释放,可以理解为try的反向操作。
MQ
总结:
只要是发生了多个服务之间的写操作
,都需要进行分布式事务控制
描述项目中采用的哪种方案(seata | MQ)
像银行业务就不需要高可用性,只要达到最终一致就可以了
互联网业务就要高可用
- seata的XA模式,CP,需要
互相等待各个分支事务提交
,可以保证强一致性
,性能差(银行业务) - seata的AT模式,AP,底层使用
undo log 实现
,性能好(互联网业务) - seata的TCC模式,AP,性能较好,不过需要
人工编码
实现(银行业务) - MQ模式实现分布式事务,在
A服务写数据
的时候,需要在同一个事务
内发送消息到另外一个事务
,异步
,性能最好(互联网业务)
9.分布式服务的接口幂等性如何设计?
幂等:多次调用方法
或者接口不会改变业务状态
,可以保证重复调用
的结果和单次调用
的结果一致。
基于RESTful API的角度对部分常见类型请求的幂等性特点进行分析
所以,只有在请求方式是POST,或者PUT情况下会出现接口不幂等的情况。
有三种解决方案:
- 数据库唯一索引(可解决新增带来的不幂等)
如果数据库表没有唯一索引,就不能保证新增操作的幂等性(新增数据时会受唯一索引影响不能添加索引重复的数据)
- token+redis(新增、修改)----性能好
创建商品、提交订单、转账、支付等操作
举例提交订单的例子
第一次请求,生成一个唯一token存入redis
,返回给前端
第二次请求,业务处理,携带之前的token
,到redis进行验证
,如果存在
,可以执行业务
,删除token
;如果不存在,则直接返回,不处理业务
这样就解决了因为网络故障页面重复下单的问题,因为token在进行第一次下单创建订单之后,就会把redis中的token删除,就算再次点击下单,发现redis没有token导致验证失败,自然不能完成下单动作
- 分布式锁(新增、修改)----性能差
原理就是
保证下单动作不受影响,直到完成下单才释放锁
,其他线程拿不到锁就马上显示失败操作就行,而且使用分布式锁要保证锁的细粒度,要精确枷锁
,不要锁住一些与原需要枷锁业务无关的业务枷锁,导致整体性能变差
10.分布式任务调度
xxl-job路由策略有哪些?
xxl-job提供了很多的路由策略,平时用的较多就是:轮询
、故障转移
、分片广播
…
xxl-job任务执行失败怎么解决?
路由策略选择故障转移
,使用健康的实例
来执行任务
设置重试次数
查看日志
+邮件告警
来通知相关负责人解决
如果有大数据量的任务同时都需要执行,怎么解决?
让多个实例一块去执行
(部署集群),路由策略分片广播
在任务执行的代码中可以获取分片总数
和当前分片
,按照取模
的方式分摊到各个实例执行
更新中-------------
素材来自----黑马程序员