一、熔断

基于feign调用场景下,实现熔断,需要以下2个步骤。

  1. 配置文件打开 Sentinel 对 Feign 的支持:feign.sentinel.enabled=true   (配置在调用方
  2. 配置文件打开 Sentinel 对 Feign 的支持:feign.sentinel.enabled=true

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

feign 熔断示列

1-如下图,在 feign上面配置回调, fallback 

/**
 * <简述>
 * <详细描述>
 * @author syf
 * @date 2023/4/26 15:47
 * @param null
 * @return null
 */
@FeignClient(value = "gulimall-seckill" , fallback = SeckillFeignServiceFallBack.class)
public interface SeckillFeignService {

    /**
     * 根据skuId查询商品是否参加秒杀活动
     * @param skuId
     * @return
     */
    @GetMapping(value = "/sku/seckill/{skuId}")
    R getSkuSeckilInfo(@PathVariable("skuId") Long skuId);

}

 fallback 编写如下: 通过实现上面 SeckillFeignService  接口

/**
 * <简述>
 * <详细描述>
 * @author syf
 * @date 2023/4/26 15:47
 * @param null
 * @return null
 */

@Component
public class SeckillFeignServiceFallBack implements SeckillFeignService {
    @Override
    public R getSkuSeckilInfo(Long skuId) {
        return R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(),BizCodeEnum.TO_MANY_REQUEST.getMsg());
    }
}

二、降级策略

官方文档:

熔断降级 · alibaba/Sentinel Wiki (github.com)icon-default.png?t=N3I4https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

1-

rt 响应时间,单位毫秒。时间窗口:该时间内不再调用

如下图 响应时间超过1 毫秒,10秒内将不再调用。

 2- 慢调用比例 

3- 异常数

 注意:

 4、使用Sentinel来保护feign远程调用,熔断;
*  1)、调用方的熔断保护:feign.sentinel.enable=true
*  2)、调用方手动指定远程服务的降级策略。远程服务被降级处理。触发我们的熔断回调方法
*  3)、超大浏览量的时候,必须牺牲一些远程服务。在服务的提供方(远程服务)指定降级策略;
*      提供方是在运行,但是不允许自己的业务逻辑,返回的是默认的降级数据(限流的数据)

三、自定义受保护的资源

3-1 基于代码方式定义降级

 注意异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。为了统计异常比例或异常数,需要通过 Tracer.trace(ex) 记录业务异常。示例:

   @SentinelResource(value = "getCurrentSeckillSkusResource",blockHandler = "blockHandler")
    @Override
    public List<SeckillSkuRedisTo> getCurrentSeckillSkus() {

        try (Entry entry = SphU.entry("seckillSkus")) {
         
        } catch (Throwable t) {
          if (!BlockException.isBlockException(t)) {
            Tracer.trace(t);
              }
           }

        return null;
    }

新增流控规则,资源名称为上面代码定义的资源名

 3-2 基于注解方式定义资源

开源整合模块,如 Sentinel Dubbo Adapter, Sentinel Web Servlet Filter 或 @SentinelResource 注解会自动统计业务异常,无需手动调用。

@SentinelResource 具体使用可以自行百度。

 demo如图:

四、网关流控

Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流的 API Gateway 进行限流。

 

4-1整合spring cloud 网关

 官网地址:

网关限流 · alibaba/Sentinel Wiki (github.com)icon-default.png?t=N3I4https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81

导入 Maven 依赖 

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
    <version>x.y.z</version>
</dependency>

这个时候请求进入,网关就能感知到请求在网关配置的路由id。

 下面展示1.70版本的控制台的网关配置新增页面,具体配置可以看官网上面地址已经贴出

 4-2自定义网关限流回调

使用时只需注入对应的 SentinelGatewayFilter 实例以及 SentinelGatewayBlockExceptionHandler 实例即可(若使用了 Spring Cloud Alibaba Sentinel,则只需按照文档进行配置即可,无需自己加 Configuration)。比如:

package com.atguigu.gulimall.gateway.config;

import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.fastjson.JSON;
import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.utils.R;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * <简述>配置网关回调
 * <详细描述>
 * @author syf
 * @date 2023/4/27 17:18
 * @return null
 */

@Configuration
public class SentinelGatewayConfig {

    public SentinelGatewayConfig() {
        GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
            //网关限流了请求,就会调用此回调
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {

                R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMsg());
                String errorJson = JSON.toJSONString(error);

                Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(errorJson), String.class);
                return body;
            }
        });
    }

}

 返回示范如下

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐