Sentinel控制台流控规则以及统一异常处理

1,000 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

一、Sentinel控制台功能的了解

1-1、实时监控

通过实时监控就可以看到接口的访问情况,可以看到实时的方位QPS,拒绝的QPS,以及响应时间 image.png

1-2、簇点链路

可以显示所有可以流控降级的规则设置的资源,这样就可以根据对应的资源进行设置。 image.png

1-3、流控规则

流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。 ==== FlowRule RT(响应时间) 1/0.2s =5

image.png image.png

1-3-1、设置QPS流控规则

1-3-1-1、选择服务

选择要流控的服务,点击流控 image.png

1-3-1-2、设置规则

选择设置QPS流控规则,为了方便测试,设置每秒超过1个QPS就触发流控 image.png

1-3-1-3、测试

频繁刷新的情况下就触发了流控规则,如下 image.png

通过上面虽然可以流控,但是信息不是我们所想要的,因此就需要之前文章提到过的@SentinelResource来处理了。如下

image.png

重启服务之后,刚刚设置的流控规则就没了(后续再介绍持久化),还需重新设置 image.png

需要注意的是一定要给,@SentinelResource设置的资源名称添加规则 image.png

image.png

这样就可以触发流控规则了 image.png

1-3-2、并发线程数

并发数控制用于保护业务线程池不被慢调用耗尽。例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。为应对太多线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离)。这种隔离方案虽然隔离性比较好,但是代价就是线程数目太多,线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。Sentinel 并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制通常在调用端进行配置。

1-3-2-1、添加新的方法

为测试线程流控添加一个新的方法,在方法内让线程睡眠5s,这样在请求进来之后,这个线程就会一直占用。

image.png

1-3-2-2、添加线程流控规则

设置线程数1、这样方便测试 image.png

1-3-2-3、测试

用chrome和firefox浏览器分别访问接口,后访问的就会被流控 image.png

1-4、BlockException异常统一处理

上面举例中需要流控或者降级的方法,都是通过设置@SentinelResource,然后使用blockHander指向异常处理方法,这样就需要为对应的方法创建其流控异常处理方法,如果异常处理都比较简答,实际我们可以进行统一异常处理,如果各个方法处理的异常有其自定义复杂的处理逻辑,就不适合统一异常处理了

1-4-1、创建统一异常处理类

通过统一异常处理类,就可以用一个异常处理类来完成异常的处理了。

@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
    Logger log= LoggerFactory.getLogger(this.getClass());
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception {
        log.info("BlockExceptionHandler BlockException================"+e.getRule());

        Result r = null;

        if (e instanceof FlowException) {
            r = Result.error(100,"接口限流了");

        } else if (e instanceof DegradeException) {
            r = Result.error(101,"服务降级了");

        } else if (e instanceof ParamFlowException) {
            r = Result.error(102,"热点参数限流了");

        } else if (e instanceof SystemBlockException) {
            r = Result.error(103,"触发系统保护规则了");

        } else if (e instanceof AuthorityException) {
            r = Result.error(104,"授权规则不通过");
        }
        //返回json数据
        response.setStatus(500);
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        new ObjectMapper().writeValue(response.getWriter(), r);
    }
}

1-4-2、添加方法

使用统一异常处理类,就不需要再给方法添加@SentinelResource注解了 image.png

1-4-3、添加流控规则

统一再次访问一下接口,就可以在sentinel控制台看到接口了 image.png

添加线程流控规则 image.png

1-4-4、测试

统一在两个不同的浏览器访问接口,被流控的接口就会显示我们设置的异常信息了 image.png