雪崩问题

雪崩问题解决

  1. 超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息。

  2. 舱壁模式(线程隔离):设定每个业务能使用的线程数,避免耗尽整个tomcat的资源。

  3. 熔断降级(快速失败):由断路器统计业务执行的异常比例,如果超过阈值则会熔断该业务,拦截访问该业务的请求。

  4. 流量控制(预防):限制业务访问的QPS,避免服务因流量的突增而发生故障。

image

启动Sentinel服务

使用docker直接部署Sentinel服务 : docker run -itd --restart=always -p 8858:8858 sentinel-dashboard:latest

进入控制台 :http://localhost:8858

SpringBoot项目接入

1.增加maven配置

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

2.增加yaml配置

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8858
      eager: true

3.代码中增加注解

 	@SentinelResource(value = "genOrder", blockHandler = "genOrderExceptionHandler", fallback = "genOrderFallbackHandler")
    @GetMapping("/genOrder")
    public String genOrder(Long productId) {
        ProductClient.ProductDTO productDTO = productClient.get(productId);
        return "订单生成成功:" + productDTO.toString();
    }

    public String genOrderExceptionHandler() {
        return "订单生成接口限流了";
    }

    public String genOrderFallbackHandler() {
        return "订单生成接口失败了";
    }

流控模式

image

在添加流控规则时,在高级选项中可以选择三种流控模式:

直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式。

关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流。(新增A的限流规则,关联资源B,当资源B触发阈值时,对资源A进行限流)

  • 场景:两个有竞争关系的资源,一个优先级高,一个优先级低,那么当优先级高的触发阈值时,就对优先级低的进行限流。用于保证优先级高的接口通畅。

链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流。(对指定的链路进行限流)

流控效果

快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常

warm up:预热模式,对超出阈值的请求同样是拒绝并抛出异常,但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。

排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于执行时长。

隔离和降级

FeignClient整合Sentinel

开启Feign的sentinel功能

feign:
	sentinel:
		enabled: true #开启Feign的Sentinel功能

添加失败降级的类

@FeignClient(value = "hikari-ai-common", path = "/ai-common/api/inner", fallbackFactory = CommonClientFactory.class)
public interface CommonClient {

    @GetMapping("v1/pay/way/enable/list")
    ResultVO<List<PayWayClient>> findEnablePayWays();
}

//失败降级的类
@Slf4j
@Component
class CommonClientFactory implements FallbackFactory<CommonClient> {

    @Override
    public CommonClient create(Throwable throwable) {
        return () -> {
            log.error("获取【支付方式】调用[common 服务]发生异常,{}", throwable);
            return null;
        };
    }
}

线程隔离

线程池隔离:
信号量隔离:

熔断降级

慢调用比例:业务响应时间(RT)大于指定时长的请求认定为慢调用请求。在指定时间内,如果请求数量超出设定的最小数量,慢调用比例大于设定的阈值,则触发熔断。

image

异常比例&异常数:统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例(或异常数)达到设定的阈值,则触发熔断。

image