第二十二章 alibaba sentinel详解-各种规则的应用

目录

一、总体规则

二、流量规则

1、QPS

2、线程数

3、关联

4、预热

5、排队等待

三、熔断降级

1、慢调用比例

2、异常比例

3、异常数

四、热点key限流

1、@SetinelReource指定别名

2、设置规则

 3、进行测试

4、@SetinelReource指定ParamFlowException 异常降级方法

5、@SetinelReource指定 业务异常 降级方法

6、参数列外项

参数例外项


学习中文官网:Home · alibaba/Sentinel Wiki · GitHub         

一、总体规则

五大规则

  •   流量规则--流量控制(flow control)
  •   降级规则--熔断降级
  •   热点规则--热点参数(Paramflow)
  •   系统规则--了解(见官网)
  •   授权规则--黑白名单控制规则
  • 资源名: 唯一名称,默认请求路径
  • 针对来源: Sentinel可以战队调用者进行限流,填写服务名。默认为default(不区分来源)
  • 阈值类型/单击阈值

               QPS(每秒中的请求数量): 当调用该api的QPS达到阈值的时候,进行限流

               线程数: 当调用该api的线程数达到阈值的时候,进行限流

  • 是否集群: 不需要集群
  • 流控模式:

               直连: api达到限流条件时,直接限流

               关联: 当关联的资源达到阈值的时候,就限流自己

               链路: 指记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈     值,如果达到阈值,就进行限流)【api级别的针对来源】

  • 流控效果:

               快速失败: 直接失败,抛异常 + Warm Up: 根据codeFactor(冷加载因子,默认为3)的值,从阈值/codeFactor,经过预热时长,才打到设置的QPS的阈值。

               匀速排队: 匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效。

       本章案例都是 基于第二十一章 中案例代码。

二、流量规则

       原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。     

1、QPS

原理:每秒中的请求次数超过设定的阈值的时候,进行限流。

例如 设置保护资源为 订单服务中的 /order/buy/{id},流控规则中阈值为2。如果没有配置规则,这1s内来多少个请求就要处理多少个请求。如果配置规则,例如阈值为1s内可以访问2个请求,若超出2个的第三个及以后的请求都会被拒接。       

  •  新建规则

  • 选择阈值QPS、流控模式直接、流控效果快速失败 

  •  进行测试

2、线程数

原理: 当调用该api的线程数达到设定的阈值,进行限流
类似于在银行办业务,同一个窗口同一时间只有一个客户在办理,其他客户必须等该客户办理完之后才可以办理

  • 设置订单服务的 OrderController 中 buy 方法

        在 buy 方法中设置延迟时间超过1s,模拟银行工作人员为顾客办理业务时间。

package com.hwadee.springcloud.controller;


import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        //每个线程进入后都要等待0.8s,例如银行业务人员给顾客办理业务时间
        try {
            Thread.sleep(800);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Product product = orderFeignService.findOrderById(id);
        return product;
    }

    @RequestMapping("/select/{id}")
    public Product selectById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }

}
  • 设置线程数请求阈值

  • 请求测试

       点击不断刷新

3、关联

原理:当关联的资源达到阈值的时候,就限流自己

例如订单的支付接口繁忙时候,则对下订单接口进行限流。本案例中订单服务中有两个资源 /order/buy/{id} 与  /order/select/{id},因为在同一个controller中,因此是关联的。我们在  /order/buy/{id} 繁忙的时候,对 /order/select/{id} 限流,所以保护的资源是 /order/select/{id},关联的资源是 /order/buy/{id},流控规则中阈值为1。当关联的资源 /order/buy/{id}的请求超出1后,资源 /order/select/{id} 会被限流。     

  •  代码
package com.hwadee.springcloud.controller;


import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        Product product = orderFeignService.findOrderById(id);
        return product;
    }

    @RequestMapping("/select/{id}")
    public Product selectById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }

}
  • 设置规则

  • 进行测试

        jmeter下载地址:压力测试工具----JMeter_爱吃面的猫的博客-CSDN博客

        压力测试访问关联资源 http://localhost:9000/order/buy/1

        当关联资源http://localhost:9000/order/buy/1 请求超出阈值后,则http://localhost:9000/order/select/1 被限流。

4、预热

定义:Warm Up ( RuleConstant.CONTROL_BEHAVIOR_MARA_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统装压垮。

应用场景:如:秒杀系统开启的瞬间,会有很多流量上来,很有可能会把系统打死,预热方式就是为了把系统保护起来, 可慢慢的把流量放进来,慢慢的把阈值增加到设定的值。

原理:根据codeFactor(冷加载因子,默认的codeFactor为3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS的阈值。

案例:阈值10+,预热时间设置5秒,系统初始化的阈值为10/3约等于3,即阈值刚开始为3,经过了5秒后阈值才慢慢升高到10。

  • 源码:
package com.hwadee.springcloud.controller;


import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        Product product = orderFeignService.findOrderById(id);
        System.out.println("/buy/{id} 执行");
        return product;
    }

    @RequestMapping("/select/{id}")
    public Product selectById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }

}
  •  设置规则

  • 进行测试

       开始不行,后来慢慢就可以了,刚开始狂点 http://localhost:9000/order/buy/1,会发现报错Blocked by Sentinel (flow limiting),然后5秒后,阈值从3->10后,会发现狂点刷新浏览器不会出现限流。

5、排队等待

让请求以均匀的请求速度通过,阈值类型必须为QPS,否则无效
设定 /order/buy/{id} 每秒1次请求,请超时的话需要排队等待,等待的超时时间为2000毫秒(即2秒)

代码

package com.hwadee.springcloud.controller;


import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        Product product = orderFeignService.findOrderById(id);
        System.out.println(Thread.currentThread().getName()+"\t"+"/buy/"+id+" 执行");
        return product;
    }

    @RequestMapping("/select/{id}")
    public Product selectById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }

}
  • 设置规则

  • 进行测试

       执行半秒后关闭。会看到控制台上依然在打印消息。

三、熔断降级

        服务熔断作用:就是防止服务雪崩现象出现。

        服务熔断:正常情况出现超时、异常、宕机等情况就是服务降级,只有当默认10秒内超过20个请求次数 或者 默认10内超过50%的请求失数 的情况,才是熔断,此时才开启熔断器。

        Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。

        当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

        Sentinel熔断降级是没有半开状态的。

    当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

1、慢调用比例

  • 1.RT:响应时间,指系统对请求作出响应的时间。
  • 2.统计时长:时间条件,在该时间段内发生的请求,单位毫秒。
  • 3.最小请求数:在统计时长内发出的请求次数。例如在统计时长1s内发出的QPS阈值是5个。
  • 4.慢调用次数:当调用的时间(响应的实际时间)>设置的RT的时间的请求次数。
  • 5.慢调用比例:在所以调用中,慢调用占有实际的比例,= 慢调用次数 / 调用次数
  • 6.比例阈值:自己设定的 , 慢调用次数 / 调用次数=比例阈值

      当平均响应时间 超出阈值 在时间窗口通过的请求>=默认5个,两个条件同时满足后,触发降级。窗口期过后关闭断路器。

  • 设置规则

        这里表示在在1000毫秒,也就是1秒内,发送请求 /order/buy/{id} 数超过5时,并且在这些请求中,平均响应时间RT超过200毫秒的有30%,则对请求进行熔断,熔断时长为20秒钟,10秒以后恢复正常。即触发条件:

  • 1s内最小请求数必须大于5
  • 慢请求 ÷ 总请求 >= 0.3

  • 代码

       前面设置RT的最长响应时间是0.2s,此处代码中设置最长响应时间为1s。

package com.hwadee.springcloud.controller;


import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Product product = orderFeignService.findOrderById(id);
        System.out.println(Thread.currentThread().getName()+"\t"+"/buy/"+id+" 执行");
        return product;
    }

    @RequestMapping("/select/{id}")
    public Product selectById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }

}
  • 进行测试

       通过JMeter测试,1秒钟发起10个线程请求 /order/buy/1 ,此时请求数>5,且每个请求的响应时间>RT的0.2s,因此触发熔断效果,停止测试以后,20秒钟以后恢复正常。

 浏览器刷新请求 http://localhost:9000/order/buy/1

2、异常比例

      异常比例(DEGRADE_GRADE_EXCEPTION_RATIo):当资源的每秒请求量>=5,并且每秒异常总数占通过量的比值超过阈值( DegradeRule中的count )之后,资源进入降级状态,即在接下的时间窗口( DegradeRule中的timeWindow,以s为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0,1.0]。

  • 代码

       设置异常,如果id<=0则抛出异常。

package com.hwadee.springcloud.controller;


import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Product product = orderFeignService.findOrderById(id);
        System.out.println(Thread.currentThread().getName()+"\t"+"/buy/"+id+" 执行");
        return product;
    }

    @RequestMapping("/select/{id}")
    public Product selectById(@PathVariable Long id) {
        if (id<=0){
            throw new RuntimeException("selectById 执行异常");
        }
        Product product = new Product();
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }

}
  • 设置规则

        设置1000毫秒即1s内最小请求是5个,如果错误请求/总的请求数超过>=阈值0.3 则触发熔断。    

  触发条件:

      1s内最小请求数大于5

      异常数/总请求数 > 0.3

  • 进行测试

        访问 http://localhost:9000/order/select/-1

       访问 http://localhost:9000/order/select/1

       通过JMeter测试,1秒钟发起10个线程请求 /order/select/-1 ,此时请求数>5,且错误请求/总的请求数>0.3,因此触发熔断效果,停止测试以后,10秒钟以后恢复正常。   

       浏览器同时访问 http://localhost:9000/order/select/1

3、异常数

        异常数( DEGRADE_GRADE_EXCEPTION_COUNT ):单位时间内异常数目超过阈值之后会进行熔断。

  • 代码:
package com.hwadee.springcloud.controller;


import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Product product = orderFeignService.findOrderById(id);
        System.out.println(Thread.currentThread().getName()+"\t"+"/buy/"+id+" 执行");
        return product;
    }

    @RequestMapping("/select/{id}")
    public Product selectById(@PathVariable Long id) {
        if (id<=0){
            throw new RuntimeException("selectById 执行异常");
        }
        Product product = new Product();
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }

}
  • 设置规则

触发条件:

    每秒请求数必须大于5

    每秒的异常数必须大于3【我们设置的阈值】

  • 进行测试

       不断刷新 http://localhost:9000/order/select/-1

四、热点key限流

       热点:即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。

比如:商品秒杀,在某一时间内对此秒杀的商品进行限流,如商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制。又如:用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制。

       热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

1、@SetinelReource指定别名

       热点参数限流时候,不能使用资源路径,只能使用资源路径的别名。资源路径别名的指定是在注解@SetinelReource中使用value属性指定。 例如 对 selectById 方法 使用 @SentinelResource(value = "selectById") 指定别名为 selectById。

package com.hwadee.springcloud.controller;


import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Product product = orderFeignService.findOrderById(id);
        System.out.println(Thread.currentThread().getName()+"\t"+"/buy/"+id+" 执行");
        return product;
    }

    @RequestMapping("/select/{id}")
    @SentinelResource(value = "selectById")
    public Product selectById(@PathVariable Long id) {
        Product product = new Product();
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }

}

2、设置规则

 3、进行测试

4、@SetinelReource指定ParamFlowException 异常降级方法

       使用 @SetinelReource中  blockHandler 属性指定降级方法,如果不指定,blockHandler会抛出异常,即BlockException异常的子异常 ParamFlowException。

  • 代码
package com.hwadee.springcloud.controller;


import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Product product = orderFeignService.findOrderById(id);
        System.out.println(Thread.currentThread().getName()+"\t"+"/buy/"+id+" 执行");
        return product;
    }

    @RequestMapping("/select/{id}")
    @SentinelResource(value = "selectById",blockHandler = "handle_selectById")
    public Product selectById(@PathVariable Long id) {
        Product product = new Product();
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }


    public Product handle_selectById(Long id, BlockException exception) {
        Product product = new Product();
        product.setName("哎吆,服务走神了,请稍后重试");
        System.out.println(product);
        return product;
    }
    
}
  • 指定规则

  • 进行测试 

5、@SetinelReource指定 业务异常 降级方法

       使用 @SetinelReource中  fallback 或则 defaultFallback 指定业务中的异常降级,其中 fallback 用于指定业务报错时候的自定义方案,defaultFallback 用于指定业务报错时候的默认方案。如果二者同时有,则选择自定义,如果没有自定义,则选择默认。

  • 代码
package com.hwadee.springcloud.controller;


import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {

    @Autowired
    IOrderFeignService orderFeignService;

    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Product product = orderFeignService.findOrderById(id);
        System.out.println(Thread.currentThread().getName()+"\t"+"/buy/"+id+" 执行");
        return product;
    }

    @RequestMapping("/select/{id}")
    @SentinelResource(value = "selectById",blockHandler = "handle_selectById",
            fallback ="fallback__selectById",
            defaultFallback = "defaultFallback_selectById")
    public Product selectById(@PathVariable Long id) {
        if (id<=0){
            throw  new RuntimeException("selectById 执行异常");
        }
        Product product = new Product();
        product.setName("selectById 执行");
        System.out.println(product);
        return product;
    }


    public Product handle_selectById(Long id, BlockException exception) {
        Product product = new Product();
        product.setName("哎吆,服务走神了,请稍后重试");
        System.out.println(product);
        return product;
    }

    public Product fallback__selectById(Long id) {
        Product product = new Product();
        product.setName("哎吆,服务走神了,请稍后重试fallback__selectById");
        System.out.println(product);
        return product;
    }

    public Product defaultFallback_selectById() {
        Product product = new Product();
        product.setName("哎吆,服务走神了,请稍后重试defaultFallback_selectById");
        System.out.println(product);
        return product;
    }

}
  • 进行测试

       先进行单次浏览,发现会发生异常,但会调用降级方法

       1s内多次刷新,即使报错,达到热点参数的阈值也会触发热点参数的条件。 

6、参数列外项

  • 设置规则

       当我们对华为手机秒杀进行限流的时候,希望对华为手机的id=5的品牌进行不限流,id=5即使例外项。

参数下标为第0个的参数(后台接收的时候知道是Long,需要选择对应的数据类型),正常情况下QPS阈值为3,超过马上被限流,但是如果id的参数值是5(id=5)的时候,他的QPS阈值为200。 

  •  进行测试

第二十一章:alibaba sentinel详解-应用入门案例

第二十三章:alibaba sentinel详解-sentinel持久化 

猜你喜欢

转载自blog.csdn.net/qq_41946216/article/details/127648697