速通springcloud--03Sentinel

Sentinel

资源
通过@SentinelResource来标识需要由sentinel管理,保护的资源。对于主流框架sentinel进行了适配,所有的Web接口均为资源

规则
通过Sentinel控制台我们可以定义流量控制,熔断降级,系统保护,来访控制,热点参数等的规则,可以将其作用于资源上。

整合sentinel

官网:https://sentinelguard.io
sentinel面板下载地址:https://github.com/alibaba/Sentinel/releases

  1. 下载好sentinel面板
  2. 引入sentinel依赖
    1. spring-cloud-starter-alibaba-sentinel
    2. 由于所有微服务都可能会用到sentinel,那么在管理微服务的模块(services模块)中添加该依赖
  3. 编写yml配置文件
    1. 要用到sentinel的微服务都有在yml文件中添加该段
spring:
    cloud:
        sentinel:
            transport:
                dashboard: localhost:8080
            eager: true #让项目一启动就让该项目连上dashboard

异常处理

当请求违背规则时会抛出一个BlockException异常,而具体来分又会抛出FlowException(流量控制异常);;ParamFlowException(热点参数异常);DegradeException(熔断降级异常);AuthorityException(权限控制异常);SystemBlockException(系统保护异常)。由于资源的不同,又会又不同的异常处理机制。

web接口异常

当对web接口的访问被sentinel规则限制会抛出该异常(可以理解为作用于controller)

自定义web请求异常访问

默认情况下会使用springmvc的SentinelWebInterceptor(web拦截器),它只会使用默认的BlockExceptionHandler进行处理(返回一个页面),而实际开发中,我们需要的是返回一个json对象。

要实现该功能我们需要使用@SentinelResource注解来标注作用的资源,然后去实现BlockExceptionHandler,并将其放入到ioc容器中即可

下面这个例子会对创建订单请求进行流量控制,并且自定义返回的错误信息为json串

1.添加流控规则

我们可以在sentinel控制台中看到名为/create的资源,该资源是一个远程调用接口,用以获取商品数据
然后点击流控,对其添加流控规则为QPS,单机阈值为1.
此时如果多次发送请求则会返回一个默认的错误页面

2.自定义异常返回结果
// model模块 com.atli.common.R
// 用于定义所有响应 
@Data
public class R{
    private Integer code;
    private String msg;
    private Object data;

    public static R ok(){
        R r = new R();
        r.setCode(200);
        return r;
    }

    public static R ok(String msg,Object data){
        R r = new R();
        r.setCode(200);
        r.setMsg(msg);
        r.setData(data);
        return r;
    }
    p    public static R error(){
        R r = new R();
        r.setCode(500);
        return r;
    }

    public static R error(Integer code,String msg){
        R r = new R();
        r.setCode(code);
        r.setMsg(msg);
        return r;
    }
}

// com.atli.order.exception.MyBlockExceptionHandler
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler{
    // 这是springMVC整合了jackson的json工具
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void handle(HttpServletRequest request,HttpServletResponse response,String resourceName,BlockException e) throws Exception{
        PrintWriter writer = response.getWriter();
        response.setContentType("application/json;charset=utf-8");
        R.error(500,resourceName+"bei1Sentinel限制:"+e.getMessage())

        writer.write(objectMapper.writeValueAsString(error));
    }
}

SentinelResource资源

@SentinelResource注解可以用来声明资源,一般用在非controller层(controller层是接口本身默认就是资源),在SentinelResourceAspect切面中,切点表达式定义了使用该注解注解的方法都会被sentinel切入

// com.atli.order.service.impl.OrderServiceImpl
// 这里将一个远程调用方法声明为资源,用以管控
// 资源会展示在sentinel控制台中,可以对其进行流控/熔断/热点/授权等设置
// blokHandle用于指定兜底回调,若没有指定则会交给SpringBoot全局异常处理器进行处理
@SentinelResource(value="createOrder",blockHandle = "createOrderFallback")
@Override
public Order createOrder(Long productId , Long userId){
    //之前写的远程调用商品服务的代码
}

// 定义兜底回调,该回调会在createOrder方法调用失败后执行(被sentinel限制)
// 要注意,该回调除开方法名外要与原方法一致,并且可以在参数列表中添加一个异常
public Order createOrderFallback(Long productId , Long userId , BlockException e){
    //兜底回调的逻辑,比如返回一个全为特殊值(0,默认等)的Order对象进行返回
}

OpenFeign调用

可以去看OpenFeign的默认返回章节

流控规则

总的来说,流控的主要目的是限制多余请求,以保护系统资源不被耗尽,保护系统的稳定性

在sentinel控制台我们可以新增流控规则,可以对来源,阈值类型,单机阈值,集群,流控模式,流控效果等进行设置

  • 资源名
    • 用以表示要进行限制的资源名称
  • 针对来源
    • 表示对资源访问的来源,默认为default,表示所有来源
    • 可以类比为http请求的发起方
  • 阈值类型
    • QPS
      • 表示在1s内最多的请求个数
    • 并发线程数
      • 效果同QPS,但由于要统计线程数,会影响性能
  • 单机阈值
    • 表示一个服务器最多能接收的请求个数
  • 是否集群
    • 若勾选,会由集群阈值模式选项,分为单机均摊和总体阈值
    • 此时单机阈值选项会变为均摊阈值
    • 单机均摊则每台阈值为设定值。总体阈值则整个集群的最大请求数
  • 流控模式
    • 直接策略
      • 直接对该资源进行限制
    • 关联策略
      • 关联资源
        • 与自身资源需要进行关联的资源
      • 当资源A和B都访问同一资源C时,若对资源A设置了关联策略,并将关联资源设置为了B,那么当访问量过大时会优先满足资源B的需求,对资源A进行限制
    • 链路策略
      • 要使用链路策略我们还需要在配置文件中对sentinel的web-context-unify设置为false,该配置项表示是否要统一web的上下文
      • 入口资源
        • 调用链路的入口
      • 在调用链路中,可能会有多条从入口到目标资源的资源路径,通过链路策略,我们可以管控从入口到目标资源路径上的资源(例如有2个并联资源,若对A不限制,那么对目标资源的限制其实作用在B上)
  • 流控效果
    • 快速失败
      • 超出阈值的请求直接抛出异常
    • Warm Up(冷启动)
      • QPS,最大请求数
      • Period 冷启动周期
      • 例:假设QPS=3,Period=3,那么当大量请求到达后QPS会从0开始,递增Period次,到达设置的QPS值,之后一直按照QPS的值进行限流
    • 排队等待
      • timeout
        • 排队超时事件
      • 当大量请求到达后,该资源会将所有请求进行排队,超过了timeout时间的请求会被丢弃
      • 例:QPS=2,timeout=3,那么每次都会将6个请求放入到队列,其余请求都会被抛弃
    • 只有快速失败支持链路和关联策略

熔断规则

雪崩效应:
当微服务集群中某个服务存在问题无法及时响应时,调用它的其他微服务就会积压请求,使得自身资源被快速消耗,无法及时响应数据。由于一个服务异常而导致一堆服务异常的这种现象被称为雪崩

熔断降级:
为了避免雪崩效应,让失败的请求快速返回不积压,切断不稳定调用的机制就称为熔断降级。
熔断降级作为保护自身的手段,通常在调用端进行配置

  • 断路器:

    • 闭合
      • 正常访问
    • 打开
      • 发生熔断,在熔断时长到达之前都拒绝访问
      • 熔断时长结束后进入半开状态
    • 半开
      • 先放行一个请求作为探测
      • 若成功则断路器闭合
      • 若失败则断路器重新打开
  • 熔断策略

    • 慢调用比例
      • 最大RT:设置统计的最大响应时长
      • 比例阈值:在统计时长内超过最大RT的请求数的比例大于比例阈值则熔断
    • 异常比例
      • 在统计时长内有超过比例阈值的异常调用(执行了兜底回调)会发生熔断
    • 异常数
      • 在统计时长内超过了设置异常数的异常请求则发生熔断

热点规则

热点是经常访问的数据。热点参数限流可以看作是一种特殊的流量控制,仅对包含热点参数的资源调用生效

要使用热点规则,需要对接受请求的api接口添加@SentinelResource注解,并指定兜底回调,之后再在sentinel控制台对其请求的参数进行限制

例如,我需要同一个用户不能重复发起请求

@GetMapping("/seckill")
@SentinelResource(value = "seckill-order",fallback = "seckillFallback")
public Order seckill(@RequestParam("userId") Long userId,@RequestParam("productId") Long productId){
    Order order = orderService.createOrder(productId,userId);
    order.setId(Long.MAX_VALUE);
    return order;
}

// sentinel异常机制中先走blockHandle异常,若无才走fallback异常
// 这里是fallback回调,使用该回调可以处理所有异常,blockHandle只能处理流控异常
public Order seckillFallback(Long userId,Long productId,Throwable exception){
    //需要兜底返回的内容
}

此时我们只需要在控制台中找到该资源,然后点击添加熔断,将参数索引设置为0,单机阈值设置为1,统计窗口时长也设置为1,那么在1s内每个用户就都只能发送一个请求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值