目录
文章目录
前言
一、解决微服务雪崩的问题
二、使用步骤
三、熔断器的使用
3.1 限流规则
3.1.1流控模式
3.1.2流控效果
3.2 隔离和降级
3.2.1 隔离
3.2.2 降级
四、sentinel规则持久化
总结
在基于 SpringCloud 构建的微服务体系中,服务间的调用链路会随着系统的演进变得越来越长,这无疑会增加了整个系统的不可靠因素。在并发流量比较高的情况下,由于网络调用之间存在一定的超时时间,链路中的某个服务出现宕机都会大大增加整个调用链路的响应时间,而瞬间的流量洪峰则会导致这条链路上所有服务的可用线程资源被打满,从而造成整体服务的不可用,这也就是我们常说的 “雪崩效应”。而在微服务系统设计的过程中,为了应对这样的糟糕情况,最常用的手段就是进行 ”流量控制“ 以及对网络服务的调用实现“熔断降级”。因此,Sentinel 就因运而生了。
Sentinel 是一款面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来保障服务的稳定性,核心思想是:根据对应资源配置的规则来为资源执行相应的流控/降级/系统保护策略
解决雪崩问题的常见方式有四种:
如何避免因瞬间高并发流量而导致服务故障?
• 流量控制如何避免因服务故障引起的雪崩问题?
• 超时处理• 线程隔离• 降级熔断
Sentinel是阿里巴巴开源的一款微服务流量控制组件。官网地址:home | Sentinel
Sentinel 具有以下特征:
• 丰富的应用场景 : Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。• 完备的实时监控 : Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。• 广泛的开源生态 : Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 Spring Cloud 、 Dubbo 、 gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel 。完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
首先下载sentinel控制台jar包
然后在该目录下打开cmd
启动该jar包
java -Dserver.port=8888 -jar sentinel-dashboard-1.8.6.jar
微服务整合Sentinel
我们在order-service中整合Sentinel,并且连接Sentinel的控制台,步骤如下:
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
然后在配置文件中接入
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8888
这样就完成了一个微服务的接入熔断 ,其他类似
在添加限流规则时,点击高级选项,可以选择三种流控模式:
• 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式• 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流• 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流
@SentinelResource("goods")
public void queryGoods() {
System.err.println("查询商品");
}• Sentinel 默认会将 Controller 方法做 context 整合,导致链路模式的流控失效,需要修改 application.yml ,添加配置:spring:
cloud:
sentinel:
web-context-unify: false # 关闭context整合
流控模式有哪些?
• 直接:对当前资源限流• 关联:高优先级资源触发阈值,对低优先级资源限流。• 链路:阈值统计时,只统计从指定资源进入当前资源的请求,是对请求来源的限流
流控效果是指请求达到流控阈值时应该采取的措施,包括三种:
比如1s 10个qps 排队等待效果就是在某这时刻 一瞬间全都进到队列里面等待 每个请求处理200ms 这个时候队列是满的 如果第一请求还没处理好,那么后面超过该队列总的等待时间的请求就会直接被拒绝,但是随着处理,后面的请求再来的时候有可能因为已经处理过了,而刚好进入到队列中等待,这时候该请求就不会被限制
流控效果有哪些?
• 快速失败: QPS 超过阈值时,拒绝新的请求• warm up : QPS 超过阈值时,拒绝新的请求; QPS 阈值是逐渐提升的,可以避免冷启动时高并发导致服务宕机。• 排队等待:请求会进入队列,按照阈值允许的时间间隔依次执行请求;如果请求预期等待时长大于超时时间,直接拒绝
热点参数限流的时候需要给该限流的控制层方法添加@SentinelResource("hot") 来让限流生效
Feign整合Sentinel
SpringCloud中,微服务调用都是通过Feign来实现的,因此做客户端保护必须整合Feign和Sentinel。
1. 修改 OrderService 的 application.yml 文件,开启 Feign 的 Sentinel 功能在配置文件中开启该功能
feign:
sentinel:
enabled: true # 开启Feign的Sentinel功能2. 给 FeignClient 编写失败后的降级逻辑① 方式一: FallbackClass ,无法对远程调用的异常做处理方式二:FallbackFactory,可以对远程调用的异常做处理,我们选择这种
先写一个降级后的处理类
@Component
public class ProductFeignFactory implements FallbackFactory {
@Override
public ProductFegin create(Throwable throwable) {
return new ProductFegin() {
@Override
public Product findById(Integer pid) {
Product product = new Product();
product.setPid(1);
product.setPname("系统繁忙");
return product;
}
};
}
}
然后开启
/**
* @author :Student王心
* @date :Created in 2023/2/11 15:30
* @description:
* fallbackFactory 远程调用微服务出现故障 则执行降级的业务代码
* @modified By:
* @version:
*/
//value里面表示服务名称,openfeign用来远程调用的,这个接口主要说明,需要调用那个微服务名称
@FeignClient(value = "xin-spring-cloud-product",fallbackFactory = ProductFeignFactory.class)
public interface ProductFegin {
//该路径还有提交方式必须跟提供者的路径和提交方式保持一致
@GetMapping("/product/getById/{pid}")
public Product findById(@PathVariable Integer pid);
}
这样就完成了对远程调用的异常处理
线程隔离的两种手段是?
• 信号量隔离• 线程池隔离信号量隔离的特点是?
• 基于计数器模式,简单,开销小线程池隔离的特点是?
• 基于线程池模式,有额外开销,但隔离控制更强
Sentinel熔断降级的策略有哪些?
• 慢调用比例:超过指定时长的调用为慢调用,统计单位时长内慢调用的比例,超过阈值则熔断• 异常比例:统计单位时长内异常调用的比例,超过阈值则熔断• 异常数:统计单位时长内异常调用的次数,超过阈值则熔断
java -Dserver.port=8888 -Dnacos.serverAddr=localhost:8848 -Dnacos.namespace=nacos的命名空间id -jar sentinel-dashboard.jar
# -Dserver.port 控制台端口号
# -Dnacos.serverAddr: nacos 地址
# -Dnacos.namespace: 你项目所在的 nacos 命名空间 如果命名空间就是public可以省略该参数
然后进入控制台使用所有带+2的进行操作就可以了
微服务接入
com.alibaba.csp
sentinel-datasource-nacos
1.8.1
修改该微服务的配置文件
spring.application.name=xin-spring-cloud-order
#配置中心
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
#额外的配置
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.properties
spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.extension-configs[0].refresh=true
#配置熔断器
spring.cloud.sentinel.transport.dashboard=localhost:8888
#控制面板修改规则后,可以通过该端口把规则发给微服务
spring.cloud.sentinel.transport.port=8719
#关闭引起链路模式的流控失败的上下文
spring.cloud.sentinel.web-context-unify=false
#开启feign的Sentinel功能
feign.sentinel.enabled=true
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.config.namespace=nacos命名空间id
spring.cloud.nacos.config.group=aaa
#配置持久化规则
spring.cloud.sentinel.datasource.aaa-flow.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.aaa-flow.nacos.namespace=${spring.cloud.nacos.config.namespace}
spring.cloud.sentinel.datasource.aaa-flow.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.aaa-flow.nacos.data-id=${spring.application.name}-flow-rules
spring.cloud.sentinel.datasource.aaa-flow.nacos.rule-type=flow
spring.cloud.sentinel.datasource.aaa-flow.nacos.data-type=json
这样就完成了持久化
待补充