微服务的保护

一、雪崩问题及解决方案

1.雪崩问题

微服务之间,一个微服务依赖多个其他的微服务。当一个微服务A依赖的一个微服务B出错时,微服务A会被阻塞,但其他不依赖于B的微服务不会受影响。

当有多个微服务依赖于B时,服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致其他服务都不可用。

那么,依赖于当前服务的其他服务随着时间的推移,最终也会变得不可用,形成级联失败,导致雪崩。

2.解决方案

2.1超时处理

设置超时时间,请求超过设置的时间没有响应,就返回错误信息,不无休止的等待。

2.2仓壁模式(隔离模式)

将系统的请求划分为一个个互不影响的区域。

对不同类型的请求进行隔离,每种类型的隔离互不影响,如果一种类型的请求线程资源耗尽,则对该后续的该类型请求直接返回,不在调用后续资源。

类似的,可以限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。

2.3断路器模式(熔断模式)

如果某个目标服务调用慢或有大量超时,此时就会熔断该服务,对于后续的调用请求,不会再继续调用目标服务,直接返回,快速释放资源。

断路器会统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。

2.4限流

熔断模式和隔离模式都属于出错后的容错处理机制,而限流模式则可以称为预防模式。

限流模式主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。这种模式不能解决服务依赖的问题,只能解决系统整体资源分配问题,因为没有被限流的请求依然有可能造成雪崩效应。

流量控制:限制业务访问的QPS,避免服务因为流量突增而故障。

3.总结

  • 什么是雪崩问题?
    • 微服务之间相互调⽤,因为调⽤链中的⼀个服务故障,引起整个链路都⽆法访问的情况。
  • 可以认为:
    • 限流是对服务的保护,避免因流量突增而故障,进而避免雪崩,是⼀种预防措施。超时处理、线程隔离、降级熔断是在部分服务故障时,将故障控制在⼀定范围,避免雪崩,是⼀种补救措施。

二、服务保护技术对比

在SpringCloud中支持多种服务保护技术:

  • Netfix Hystrix
  • Sentinel
  • Resilience4J

|---------|----------------------------------|------------------------------|
| | Sentinel | Hystrix |
| 隔离策略 | 信号量隔离 | 线程池隔离/信号量隔离 |
| 熔断降级策略 | 基于慢调用比例或异常比例 | 基于失败比率 |
| 实时指标实现 | 滑动窗口 | 滑动窗口(基于RxJava) |
| 规则配置 | 支持多种数据源 | 支持多种数据源 |
| 扩展性 | 多个扩展点 | 插件的形式 |
| 基于注解的支持 | 支持 | 支持 |
| 限流 | 基于QPS,支持基于调用关系的限流 | 有限的支持 |
| 流量整形 | 支持慢启动 | 不支持 |
| 系统自适应保护 | 支持 | 不支持 |
| 控制台 | 开箱即用,可配置规则、查看秒级监控、机器发现等 | 不完善 |
| 常见框架的适配 | Servlet、Spring Cloud、Dubbo、gRPC等 | Servlet、Spring Cloud Netflix |

三、Sentinel介绍和安装

1.初始Sentinel

Sentinel是阿里巴巴开源的⼀款微服务流量控制组件。官网地址:https://sentinelguard.io/zh-cn/index.html

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

2.安装Sentinel

将从官网下载的jar包放在任意非中文目录下,执行命令:

java -jar sentinel-dashboard-1.8.1.jar

若修改Sentinel的默认端口、账户、密码,可使用以下配置:

  • 默认端口 server.port 默认为8080
  • 账户 sentinel.dashboard.auth.username 默认为sentinel
  • 密码 sentinel.dashboard.auth.password 默认为sentinel

修改端口号的命令为:

java -Dserver.port=8090 -jar sentinel-dashboard-1.8.1.jar

3.访问Sentinel

访问http://localhost:8080(若为修改则为8080,修改后则为自己设置的端口号),即可看到Sentinel的控制台。

登录后发现是空白的,因为还没有和微服务整合到一起。

四、微服务整合Sentinel

我们在shop-order中整合Sentinel,并连接Sentinel的控制台。

1.引入Sentinel依赖

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2.在yml文件,配置控制台

spring: 
 cloud: 
   sentinel: 
     transport: 
       dashboard: localhost:8080 

3.访问

localhost:8091/order/update,触发sentinel的监控。

查看sentinel的控制台

五、流量控制

解决雪崩的方案之一:限流,是为了避免服务因突发的流量而发生故障,是预防措施。

1.簇点链路

当请求进入微服务时,首先会访问DispatcherServlet,然后进入Controller、Service、Mapper,这样的⼀个调用链就叫做簇点链路。簇点链路中被监控的每⼀个接口就是⼀个资源。

默认情况下sentinel会监控SpringMVC的每⼀个端点(Endpoint,也就是controller中的方法),因此SpringMVC的每⼀个端点(Endpoint)就是调用链路中的⼀个资源。

流控和熔断都是针对簇点链路中的资源来设置,因此可点击对应资源后面的按钮来设置规则:

  • 流控:流量控制
  • 降级:降级熔断
  • 热点:热点参数限流,是限流的一种
  • 授权:请求的权限控制

2.设置流控规则

要求:给/order/prod/{pid}设置流控规则,QPS不能超过5

2.1在sentinel控制台添加限流规则

其中的QPS为每秒查询率,即每秒的响应次数,也就是最大吞吐能力,QPS=请求数req/秒sec

2.2利用jmeter测试

  • 双击jmeter.bat启动jmeter

即可打开jmeter的界面

  • 添加线程组

线程数:代表用户数量

时间:代表用户访问时间

10个线程要在2秒内访问完,那每秒就是访问5个线程

QPS=10/2=5,超过了单机阈值2,所以每秒的5个线程只成功2个,剩下的3个线程会请求失败。

循环次数:代表每个用户的访问次数

  • 添加http请求

端口号:写的是sentinel中资源/order/prod/{pid}的端口号8091

路径:写的是给资源添加流控规则就写那个资源,/order/prod/{pid}

  • 察看结果树
  • 启动测试计划

方式一:单击上面任务栏的启动符号(适用于测试计划中只有一个线程)

方式二:右键单击线程启动(适用于测试计划中有多个线程)

结果:可以看到,成功的请求每次只有2个

相关推荐
架构文摘JGWZ14 分钟前
Java 23 的12 个新特性!!
java·开发语言·学习
leon62515 分钟前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab
拾光师1 小时前
spring获取当前request
java·后端·spring
aPurpleBerry1 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j
锦亦之22331 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
我是苏苏1 小时前
Web开发:ABP框架2——入门级别的增删改查Demo
java·开发语言
姜太公钓鲸2331 小时前
c++ static(详解)
开发语言·c++
菜菜想进步1 小时前
内存管理(C++版)
c语言·开发语言·c++
xujinwei_gingko1 小时前
Spring IOC容器Bean对象管理-Java Config方式
java·spring
2301_789985941 小时前
Java语言程序设计基础篇_编程练习题*18.29(某个目录下的文件数目)
java·开发语言·学习