Spring Cloud Alibaba【授权规则、系统自适应限流、SentinelResource注解配置详解之只配 置fallback】(八)

  

目录

分布式流量防护_授权规则

分布式流量防护_系统自适应限流

分布式流量防护_SentinelResource注解配置详解之只配 置fallback

分布式流量防护_SentinelResource配置详解之只配置 blockHandler


分布式流量防护_授权规则

授权规则 

授权规则可以对调用方的来源做控制,有白名单和黑名单两种方式。

1、白名单:来源(origin)在白名单内的调用者允许访问

2、黑名单:来源(origin)在黑名单内的调用者不允许访问

点击左侧菜单的授权,可以看到授权规则:

资源名:就是受保护的资源,例如/payment/{query}

流控应用:是来源者的名单,

     如果是勾选白名单,则名单中的来源被许可访问。

     如果是勾选黑名单,则名单中的来源被禁止访问。 

注意: 我们允许请求从gateway到payment服务,不允许浏览器访问 payment,那么白名单中就要填写网关的来源名称 (origin)。 

案列实现 

创建网关工程cloud-gateway9090

 

POM文件引入依赖 

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
            <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

编写主启动类

@EnableDiscoveryClient
@SpringBootApplication
@Slf4j
public class Gateway9090 {
    public static void main(String[] args) {
       SpringApplication.run(Gateway9090.class,args);
        log.info("********** Gateway9090 启动成功 *********");
   }
}

创建配置文件

server:
 port: 9090
spring:
 application:
   name: gateway
 cloud:
   nacos:
     discovery:
       server-addr: 192.168.66.100:8848
   gateway:
     routes:
       - id: payment
         uri: lb://payment-provider-sentinel
         predicates:
           - Path=/payment/*

测试网关服务

发送请求http://localhost:9090/payment/query

如何获取origin 

Sentinel是通过RequestOriginParser这个接口的parseOrigin来获取请求的来源的。 

public interface RequestOriginParser {
    /**
     * 从请求request对象中获取origin,获取方式自定义
     */
    String parseOrigin(HttpServletRequest request);
}

 注意: 这个方法的作用就是从request对象中,获取请求者的origin值并返回。默认情况下,sentinel不管请求者从哪里来,返回值永远是default,也就是说一切请求的来源都被认为是一样的值default。因此,我们需要自定义这个接口的实现,让不同的请求,返回不同的origin。

支付微服务定义一个RequestOriginParser的实现类

package cn.itcast.order.sentinel;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
@Component
public class HeaderOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        // 1.获取请求头
        String origin = request.getHeader("origin");
        // 2.非空判断
        if (StringUtils.isEmpty(origin)) {
            origin = "blank";
       }
        return origin;
   }
}

 给网关添加请求头

既然获取请求origin的方式是从reques-header中获取origin值,我们必须让所有从gateway路由到微服务的请求都带上origin头。

spring:
 cloud:
   gateway:
     default-filters:
       - AddRequestHeader=origin,gateway

 注意: 这样,从gateway路由的所有请求都会带上origin头,值为 gateway。而从其它地方到达微服务的请求则没有这个头。

配置授权规则 

接下来,我们添加一个授权规则,放行origin值为gateway的请求。

 

配置规则 

测试网关请求

请求localhost:9090/payment/query 

测试非网关请求 

实时效果反馈

1.Sentinel是通过_______这个接口的parseOrigin来获取请求的来源的。

A Origin

B RequestOrigin

C RequestOriginParser

D 以上都是错误 

分布式流量防护_系统自适应限流

引入系统自适应限流的主要的目的 

1、保证系统不被拖垮

2、在系统稳定的前提下保证系统的吞吐量。目前我们接触的限流的防护思路都是设定一个指标(阈 值),例如系统的负载 load 超过某个阔值后就阻止或减少流量的继续进入,当系统负载降低到某 一水平后则恢复流量的进入。通常都是被动的,其实际效果取决于阈值设置是否合理,但往往设置 合理不是一件容易的事情。

系统规则 

Sentinel的系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等 几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

 

系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量( EntryType.IN ),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。 

 

系统规则支持以下的模式 

Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保 护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系 统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5 。

CPU usage:当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。

平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。

并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。

入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

配置系统规则

 

添加规则

 

实时效果反馈

1.Sentinel中系统自适应限流主要目的是____。

A 在保证稳定的前提下,保持系统的最大吞吐量

B 减少响应时间

C 解决高并发问题

D 解决服务雪崩

2.Sentinel系统保护规则是___整体维度的,而不是__维度的,并且 仅对入口流量生效。

A 资源、接口

B 接口、方法

C 应用、资源

D 应用、接口 

分布式流量防护_SentinelResource注解配置详解之只配 置fallback

 

服务降级功能,但是只是限制后,返回不可控的结果肯定是不行的,我们还要保证调用者在调用那些被限制的服务时候,不管是不是被限制,都要让他们拿到一个合理的结果,而不是扔回去一个异常就完事了。 

Sentinel提供了这样的功能,让我们可以另外定义一个方法来代替 被限制或异常服务返回数据,这就是fallback和blockHandler。

1、fallback:若本接口出现未知异常,则调用fallback指定的接口。

2、blockHandler:若本次访问被限流或服务降级,则调用blockHandler指定的接口。 

@SentinelResource注解用于定义资源,并提供可选的 BlockException 异常处理(仅处理Sentinel控制台配置相关异常) 和fallback 配置项(运行时异常以及自定义异常)。 

注解属性 

1、value :资源名称,必需项(不能为空)

2、entryType :entry 类型,可选项(默认为 EntryType.OUT )

3、blockHandler / blockHandlerClass : blockHandler 对应处理 BlockException 的函数名称,可选 项。blockHandler 函数访问范围需要是 public ,返回类型需要与原方法相匹配,参数类型需要和 原方法相匹配并且最后加一个额外的参数,类型为 BlockException 。blockHandler 函数默认需要 和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

4、fallback / fallbackClass :fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于 很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面 排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。

5、defaultFallback (since 1.6.0):默认的 fallback 函数名称

6、exceptionsToIgnore (since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会 进入 fallback 逻辑中,而是会原样抛出。

只配置fallback 

此回调是针对接口出现异常了,就进入此fallback方法。

    /**
     * 根据id查询支付信息
     * @param id
     * @return
     */
    @SentinelResource(value = "testfallback",fallback = "testFallback")
    @GetMapping("findById")
    public String findById(String id){
        if (id.equals("1")){
            throw  new RuntimeException("出异常了。");
       }
        return  iPaymentFeginService.findById(id);
   }
   // 降级
    public String testFallback(String id,Throwable e){
        return "系统异常了";
   }

代码看出,只要请求http://localhost:80/order/findById?id=1 ,接口就会报异常,继而会调用fallback中的方法,走到了testFallback 方法中。

外置类

fallback 函数位置是有要求的,必须和原方法在同一个类中,但在实际需求中,我们需要放在其他类中。@SentinelResource提供了通过fallbackClass指定对应的类的Class对象,添加一个static,否则无法解析。

@Component
public class PaymentServiceFallback {
    /**
     * 降级方法
     * @return
     */
    public static String findByIdFallBalk(String id,Throwable e) {
        return "支付系统服务繁忙稍等一会~~~~";
   }
}

修改注解

  @SentinelResource(value = "testfallback",fallbackClass = PaymentServiceFallback.class,fallback = "findByIdFallBalk")
    @GetMapping("findById")
    public String findById(String id){
        if (id.equals("1")){
            throw  new RuntimeException("出异常了。");
       }
        return  iPaymentFeginService.findById(id);
   }

实时效果反馈

1.Sentinel中SentinelResource注解属性falllback处理____异常。

A 热点异常

B 限流异常

C 权限异常

D 接口异常

分布式流量防护_SentinelResource配置详解之只配置 blockHandler

 

 超出流量限制的部分是否会进入到blockHandler的方法,要注意是超出流量限制的请求调用,会进入blockHandler方法。

  /**
     * 根据id查询支付信息
     * @param id
     * @return
     */
    @SentinelResource(value = "testfallback",blockHandler = "testblockHandler")
    @GetMapping("findById")
    public String findById(String id){
        if (id.equals("1")){
            throw  new RuntimeException("出异常了。");
       }
        return iPaymentFeginService.findById(id);

 降级处理

/**
     * 降级处理
     * @param id
     * @param e
     * @return
     */
    public String testblockHandler(String id,BlockException e){
        return "限流降级处理";
   }

外置类

 /**
     * 降级处理
     * @param id
     * @param e
     * @return
     */
   public Static String testblockHandler(String id,BlockException e){
       return "限流降级处理";
   }

总结

1、流控的blockHandler自定义资源必须为public static 函数 @SentinelResource注解的value与@RequestMapping的value不一样

2、流控规则配置的资源名与@SentinelResource注解的value保持一致,才会执行 @SentinelResource注解里定义的兜底方法

3、注意blockHandler 是对应处理 BlockException 的函数,而不是BlockedException

实时效果反馈

1.Sentinel中SentinelResource注解属性blackHeader处理____异 常。

A 热点异常

B 限流异常

C 权限异常

D Sentinel控制台配置相关异常 

猜你喜欢

转载自blog.csdn.net/m0_58719994/article/details/131868146
今日推荐