Sentinel用法解析

目录

一.Sentinel概述

1.Sentinel介绍

2.Sentinel核心组件

3.Sentinel基本概念

二.Sentinel核心功能

1.流量控制

2.熔断降级

三.SpringBoot整合Sentinel

1.gateway引入依赖

2.sentinel控制台搭建

3.gateway配置文件修改

4.启动gateway服务查看sentinel控制台

四.Sentinel使用

1.@SentinelResource注解

2.Sentinel的规则

3.OpenFeign支持

4.gateway规则配置

五.Sentinel控制台使用

1.实时监控

2.流控规则

 3.降级规则

4.热点数据


一.Sentinel概述

1.Sentinel介绍

        https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5

        Sentinel是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。

2.Sentinel核心组件

(1)核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

(2)控制台(Dashboard):控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。

3.Sentinel基本概念

        <1> 资源:资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

        <2> 规则:围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

二.Sentinel核心功能

1.流量控制

        Sentinel作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如图

Sentinel用法解析_第1张图片

2.熔断降级

         当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。

三.SpringBoot整合Sentinel

1.gateway引入依赖



    com.alibaba.cloud
    spring-cloud-starter-alibaba-sentinel
    2.2.5.RELEASE

2.sentinel控制台搭建

(1)下载Sentinel控制台jar包地址:https://github.com/alibaba/Sentinel/releases

Sentinel用法解析_第2张图片 源码地址:https://github.com/alibaba/Sentinel/releases

(2)启动:java -jar sentinel-dashboard-1.8.3.jar 启动,默认端口是8080

(3)登录:http://localhost:8080/     用户名密码都是:sentinel

3.gateway配置文件修改

spring:
  cloud:
    sentinel:
      transport:
        port: 8179
        dashboard: 127.0.0.1:8080

注意:

(1)这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互,比如限流规则拉取。

(2)配置信息现在是存储到nacos中,到nacos进行配置更改。

4.启动gateway服务查看sentinel控制台

Sentinel用法解析_第3张图片

四.Sentinel使用

1.@SentinelResource注解

@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。

注意该注解只能作用在实现类,不能作用在接口上面

@SentinelResource注解包含一下属性:

(1)vale

        资源名称,必需项,因为需要通过resource name找到对应的规则,这个是必须配置的。 ​ 定义资源名,该名称将会显示在控制台中,并且在定义流控以及熔断降级规则时,指定资源名称。

(2)entryType

        入口类型,可选项: EntryType.IN和EntryType.OUT(默认为 EntryType.OUT)

public enum EntryType {
    IN("IN"),
    OUT("OUT");
}

(3)blockHandler

        对应处理 BlockException 的函数名称,可选项。

(4)blockHandlerClass

        ​ blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

(5)fallback

        函数名称,可选项,仅针对降级功能生效(DegradeException)。fallback 函数的访问范围需要是 public,参数类型和返回类型都需要与原方法相匹配,并且需要和原方法在同一个类中。业务异常不会进入 fallback 逻辑。

(6)fallbackClass

        fallbackClass的应用和blockHandlerClass类似,fallback 函数默认需要和原方法在同一个类中。 ​ 若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

(7)defaultFallback

        如果没有配置defaultFallback方法,默认都会走到这里来,默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑,默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理,若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。

(8)exceptionsToIgnore

        用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

2.Sentinel的规则
 

(1)流量控制规则

(2)熔断降级规则

(3)系统保护规则

(4)访问控制规则

(5)热点规则

3.OpenFeign支持

Sentinel 适配了 Feign 组件,使用步骤如下

(1)需要在服务调用方加入依赖



    com.alibaba.cloud
    spring-cloud-starter-alibaba-sentinel
    2.2.5.RELEASE



    org.springframework.cloud
    spring-cloud-starter-openfeign

(2)服务调用方配置文件中开启Feign支持 sentinel

feign:
    #开启Sentinel对Feign的支持
    sentinel:
        enabled: true

(3)远程调用代码如下

调用方

@RestController
@RequestMapping("server1")
@Slf4j
public class DemoServer1Controller {

    @Autowired
    private Server2Feign server2Feign;

    @RequestMapping("/demo1")
    public String demo1(){
        String server2Result = server2Feign.demo2("promote msg from server1");
        return server2Result;
    }
}

公共调用Feign接口

@FeignClient(name = "demo-server2")
public interface Server2Feign {

    @GetMapping("/server2/demo2/{param}")
    public String demo2(@PathVariable(value = "param") String param);
}

被调用方

@RestController
@RequestMapping("server2")
@Slf4j
public class DemoServer2Controller {

    @RequestMapping("/demo2/{param}")
    public String demo2(@PathVariable(value = "param") String param){
        if (param.startsWith("promote")){
            throw new RuntimeException("信息不存在");
        }
        return "收到server1的msg:"+param;
    }
}

在被调用方,人为制造异常,访问接口返回如下

注意:服务出现异常,可以再被调用方降级,也可以在调用方降级

下面介绍在调用方进行降级

fallback

(1)在demo-api中创建公共Feign接口的实现类

@Component
public class FallbackServer2Feign implements Server2Feign {
    @Override
    public String demo2(String param) {
        return "系统繁忙,走降级逻辑~";
    }
}

(2)在接口的注解上指定降级处理类

@FeignClient(name = "demo-server2",fallback = FallbackServer2Feign.class)
public interface Server2Feign {

    @GetMapping("/server2/demo2/{param}")
    public String demo2(@PathVariable(value = "param") String param);
}

(3)再次测试,看是否走到降级逻辑

fallbackFactory

我们可以为 DriverFeign 接口创建一个降级处理的工厂对象,在工厂对象中处理程序异常降级处理方法,用工厂对象处理可以拿到异常信息,代码如下

(1)创建工厂对象

@Component
public class Server2FallbackFactory implements FallbackFactory {
    @Override
    public Server2Feign create(Throwable throwable) {
        return new Server2Feign() {
            @Override
            public String demo2(String param) {
                return "系统繁忙,走fallbackFactory降级逻辑~";
            }
        };
    }
}

(2)在接口注解上指定工厂类

@FeignClient(name = "demo-server2",fallbackFactory = Server2FallbackFactory.class)
public interface Server2Feign {

    @GetMapping("/server2/demo2/{param}")
    public String demo2(@PathVariable(value = "param") String param);
}

(3)重新启动测试,看是否走到工厂类降级逻辑

4.gateway规则配置

(1)新增gateway配置类,配置规则信息

@Configuration
public class GatewayConfiguration {

    private final List viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfiguration(ObjectProvider> viewResolversProvider,
                                ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        // Register the block exception handler for Spring Cloud Gateway.
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }


    @PostConstruct
    public void doInit() {
        // 自定义 api 分组
        initCustomizedApis();
        // 初始化网关流控规则
        initGatewayRules();
    }



    private void initCustomizedApis() {
        Set definitions = new HashSet<>();
        ApiDefinition api1 = new ApiDefinition("customer_api")
                .setPredicateItems(new HashSet() {{
                    add(new ApiPathPredicateItem().setPattern("/order/**")
                            /**
                             * 匹配策略:
                             * URL_MATCH_STRATEGY_EXACT:url精确匹配
                             * URL_MATCH_STRATEGY_PREFIX:url前缀匹配
                             * URL_MATCH_STRATEGY_REGEX:url正则匹配
                             */
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});
        definitions.add(api1);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }

    private void initGatewayRules() {
        Set rules = new HashSet<>();

        rules.add(new GatewayFlowRule("hailtaxi-driver") // 资源名称,可以是网关中的 routeid或者用户自定义的 API分组名称
                .setCount(2) // 限流阈值
                .setIntervalSec(10) // 统计时间窗口默认1s
                .setGrade(RuleConstant.FLOW_GRADE_QPS) // 限流模式
                /**
                 * 限流行为:
                 * CONTROL_BEHAVIOR_RATE_LIMITER 匀速排队
                 * CONTROL_BEHAVIOR_DEFAULT 快速失败(默认)
                 * CONTROL_BEHAVIOR_WARM_UP:
                 * CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER:
                 */
                .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
                //匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效
                .setMaxQueueingTimeoutMs(1000)
                /**
                 * 热点参数限流配置
                 * 若不设置,该网关规则将会被转换成普通流控规则;否则会转换成热点规则
                 */
                .setParamItem(new GatewayParamFlowItem()
                        /**
                         * 从请求中提取参数的策略:
                         * PARAM_PARSE_STRATEGY_CLIENT_IP
                         * PARAM_PARSE_STRATEGY_HOST
                         * PARAM_PARSE_STRATEGY_HEADER
                         * PARAM_PARSE_STRATEGY_URL_PARAM
                         */
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                        /**
                         * 若提取策略选择 Header 模式或 URL 参数模式,
                         * 则需要指定对应的 header 名称或 URL 参数名称。
                         */
                        .setFieldName("token")
                        /**
                         * 参数的匹配策略:
                         * PARAM_MATCH_STRATEGY_EXACT
                         * PARAM_MATCH_STRATEGY_PREFIX
                         * PARAM_MATCH_STRATEGY_REGEX
                         * PARAM_MATCH_STRATEGY_CONTAINS
                         */
                        .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_EXACT)
                        //参数值的匹配模式,只有匹配该模式的请求属性值会纳入统计和流控
                        .setPattern("123456") // token=123456 10s内qps达到2次会被限流
                )
        );

        rules.add(new GatewayFlowRule("customer_api")
                /**
                 * 规则是针对 API Gateway 的 route(RESOURCE_MODE_ROUTE_ID)
                 * 还是用户在 Sentinel 中定义的 API 分组(RESOURCE_MODE_CUSTOM_API_NAME),默认是 route。
                 */
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                .setCount(2)
                .setIntervalSec(1)
                .setGrade(RuleConstant.FLOW_GRADE_QPS)
        );
        GatewayRuleManager.loadRules(rules);
    }


}

(2)启动测试

        接口一10秒内请求超过2次会 被限流

        接口二1秒内qps达到2次会被限流

五.Sentinel控制台使用

1.实时监控

        同一个服务下的所有机器的簇点信息会被汇总,并且秒级地展示在"实时监控"下。

        注意:实时监控仅存储 5 分钟以内的数据,如果需要持久化,需要通过调用实时监控接口来定制。 

实时监控接口文档参照如下连接编写

https://github.com/alibaba/Sentinel/wiki/%E5%AE%9E%E6%97%B6%E7%9B%91%E6%8E%A7

通过接口拿到的数据如下图所示:

Sentinel用法解析_第4张图片

2.流控规则

我们可以在【流控规则】页面中新增,点击【流控规则】进入页面新增页面,如下图:

Sentinel用法解析_第5张图片

资源名:可以和请求路径保持一致,

流控模式为QPS,触发流控执行阈值为1

通过上面的留空规则配置,下面的接口访问1次就被限流了。

http://localhost:8000/server1/demo1接口访问一次后被限流如下图

 3.降级规则

我们可以选择 降级规则>新增降级规则 ,如下图:

Sentinel用法解析_第6张图片

 降级规则的熔断策略有3种,分别是慢调用比例、异常比例、异常数,和程序中是一样的。

4.热点数据

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

Sentinel用法解析_第7张图片

你可能感兴趣的:(java,架构师,sentinel,java,微服务)