美文网首页老男孩的成长之路
详解微服务之Spring Cloud Alibaba Senti

详解微服务之Spring Cloud Alibaba Senti

作者: Java入门到入坟 | 来源:发表于2020-10-29 10:33 被阅读0次

    推荐阅读:

    Sentinel 介绍

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

    Sentinel 具有以下特征:

    • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。

    • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

    • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

    • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

    如何使用 Sentinel

    如果要在您的项目中引入 Sentinel,使用 group ID 为 com.alibaba.cloud 和 artifact ID 为 spring-cloud-starter-alibaba-sentinel 的 starter。

    [source,yaml]
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    

    下面这个例子就是一个最简单的使用 Sentinel 的例子:

    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(ServiceApplication.class, args);
        }
    
    }
    
    @RestController
    public class TestController {
    
        @GetMapping(value = "/hello")
        @SentinelResource("hello")
        public String hello() {
            return "Hello Sentinel";
        }
    
    }
    

    @SentinelResource 注解用来标识资源是否被限流、降级。上述例子上该注解的属性 'hello' 表示资源名。

    @SentinelResource 还提供了其它额外的属性如 blockHandlerblockHandlerClassfallback 用于表示限流或降级的操作,更多内容可以参考 Sentinel注解支持。

    以上例子都是在 WebServlet 环境下使用的,Sentinel 目前已经支持 WebFlux,需要配合 spring-boot-starter-webflux 依赖触发 sentinel-starter 中 WebFlux 相关的自动化配置。

    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(ServiceApplication.class, args);
        }
    
    }
    
    @RestController
    public class TestController {
    
        @GetMapping("/mono")
        @SentinelResource("hello")
        public Mono<String> mono() {
        return Mono.just("simple string")
                .transform(new SentinelReactorTransformer<>("otherResourceName"));
        }
    
    }
    
    Sentinel 控制台

    Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。

    注意: 集群资源汇总仅支持 500 台以下的应用集群,有大概 1 - 2 秒的延时。

    Figure 3. Sentinel Dashboard

    开启该功能需要3个步骤:

    获取控制台

    您可以从 release 页面 下载最新版本的控制台 jar 包。

    您也可以从最新版本的源码自行构建 Sentinel 控制台:

    • 下载 控制台 工程

    • 使用以下命令将代码打包成一个 fat jar: mvn clean package

    启动控制台

    Sentinel 控制台是一个标准的 SpringBoot 应用,以 SpringBoot 的方式运行 jar 包即可。

    java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
    

    如若8080端口冲突,可使用 -Dserver.port=新端口 进行设置。

    配置控制台信息

    spring:
      cloud:
        sentinel:
          transport:
            port: 8719
            dashboard: localhost:8080
    

    这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。

    更多 Sentinel 控制台的使用及问题参考: Sentinel控制台

    OpenFeign 支持

    Sentinel 适配了 OpenFeign 组件。如果想使用,除了引入 sentinel-starter 的依赖外还需要 2 个步骤:

    • 配置文件打开 sentinel 对 feign 的支持:feign.sentinel.enabled=true

    • 加入 openfeign starter 依赖使 sentinel starter 中的自动化配置类生效:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    

    这是一个 FeignClient 的简单使用示例:

    @FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
    public interface EchoService {
        @GetMapping(value = "/echo/{str}")
        String echo(@PathVariable("str") String str);
    }
    
    class FeignConfiguration {
        @Bean
        public EchoServiceFallback echoServiceFallback() {
            return new EchoServiceFallback();
        }
    }
    
    class EchoServiceFallback implements EchoService {
        @Override
        public String echo(@PathVariable("str") String str) {
            return "echo fallback";
        }
    }
    

    Feign 对应的接口中的资源名策略定义:httpmethod:protocol://requesturl@FeignClient 注解中的所有属性,Sentinel 都做了兼容。

    EchoService 接口中方法 echo 对应的资源名为 GET:http://service-provider/echo/{str}

    RestTemplate 支持

    Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造 RestTemplate bean的时候需要加上 @SentinelRestTemplate 注解。

    @Bean
    @SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    

    @SentinelRestTemplate 注解的属性支持限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)的处理。

    其中 blockHandlerfallback 属性对应的方法必须是对应 blockHandlerClassfallbackClass 属性中的静态方法。

    该方法的参数跟返回值跟 org.springframework.http.client.ClientHttpRequestInterceptor#interceptor 方法一致,其中参数多出了一个 BlockException 参数用于获取 Sentinel 捕获的异常。

    比如上述 @SentinelRestTemplate 注解中 ExceptionUtilhandleException 属性对应的方法声明如下:

    public class ExceptionUtil {
        public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
            ...
        }
    }
    

    应用启动的时候会检查 @SentinelRestTemplate 注解对应的限流或降级方法是否存在,如不存在会抛出异常

    @SentinelRestTemplate 注解的限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)属性不强制填写。

    当使用 RestTemplate 调用被 Sentinel 熔断后,会返回 RestTemplate request block by sentinel 信息,或者也可以编写对应的方法自行处理返回信息。这里提供了 SentinelClientHttpResponse 用于构造返回信息。

    Sentinel RestTemplate 限流的资源规则提供两种粒度:

    • httpmethod:schema://host:port/path:协议、主机、端口和路径

    • httpmethod:schema://host:port:协议、主机和端口

    https://www.taobao.com/test 这个 url 并使用 GET 方法为例。对应的资源名有两种粒度,分别是 GET:https://www.taobao.com 以及 GET:https://www.taobao.com/test

    动态数据源支持

    SentinelProperties 内部提供了 TreeMap 类型的 datasource 属性用于配置数据源信息。

    比如配置 4 个数据源:

    spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json
    spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
    
    #spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
    #spring.cloud.sentinel.datasource.ds1.file.data-type=custom
    #spring.cloud.sentinel.datasource.ds1.file.converter-class=org.springframework.cloud.alibaba.cloud.examples.JsonFlowRuleListConverter
    #spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
    
    spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848
    spring.cloud.sentinel.datasource.ds2.nacos.data-id=sentinel
    spring.cloud.sentinel.datasource.ds2.nacos.group-id=DEFAULT_GROUP
    spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
    spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
    
    spring.cloud.sentinel.datasource.ds3.zk.path = /Sentinel-Demo/SYSTEM-CODE-DEMO-FLOW
    spring.cloud.sentinel.datasource.ds3.zk.server-addr = localhost:2181
    spring.cloud.sentinel.datasource.ds3.zk.rule-type=authority
    
    spring.cloud.sentinel.datasource.ds4.apollo.namespace-name = application
    spring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = sentinel
    spring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = test
    spring.cloud.sentinel.datasource.ds4.apollo.rule-type=param-flow
    

    这种配置方式参考了 Spring Cloud Stream Binder 的配置,内部使用了 TreeMap 进行存储,comparator 为 String.CASE_INSENSITIVE_ORDER

    d1, ds2, ds3, ds4 是 ReadableDataSource 的名字,可随意编写。后面的 filezknacos , apollo 就是对应具体的数据源。它们后面的配置就是这些具体数据源各自的配置。

    每种数据源都有两个共同的配置项: data-typeconverter-class 以及 rule-type

    data-type 配置项表示 Converter 类型,Spring Cloud Alibaba Sentinel 默认提供两种内置的值,分别是 jsonxml (不填默认是json)。如果不想使用内置的 jsonxml 这两种 Converter,可以填写 custom 表示自定义 Converter,然后再配置 converter-class 配置项,该配置项需要写类的全路径名(比如 spring.cloud.sentinel.datasource.ds1.file.converter-class=org.springframework.cloud.alibaba.cloud.examples.JsonFlowRuleListConverter)。

    rule-type 配置表示该数据源中的规则属于哪种类型的规则(flowdegradeauthoritysystem, param-flow, gw-flow, gw-api-group)。

    当某个数据源规则信息加载失败的情况下,不会影响应用的启动,会在日志中打印出错误信息。

    默认情况下,xml 格式是不支持的。需要添加 jackson-dataformat-xml 依赖后才会自动生效。

    关于 Sentinel 动态数据源的实现原理,参考: 动态规则扩展

    Zuul 支持

    参考 Sentinel 网关限流

    若想跟 Sentinel Starter 配合使用,需要加上 spring-cloud-alibaba-sentinel-gateway 依赖,同时需要添加 spring-cloud-starter-netflix-zuul 依赖来让 spring-cloud-alibaba-sentinel-gateway 模块里的 Zuul 自动化配置类生效:

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    

    Spring Cloud Gateway 支持

    参考 Sentinel 网关限流

    若想跟 Sentinel Starter 配合使用,需要加上 spring-cloud-alibaba-sentinel-gateway 依赖,同时需要添加 spring-cloud-starter-gateway 依赖来让 spring-cloud-alibaba-sentinel-gateway 模块里的 Spring Cloud Gateway 自动化配置类生效:

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    

    Sentinel 对外暴露的 Endpoint

    Sentinel 内部提供了一个 Endpoint, 对应的 endpoint id 为 sentinel

    Endpoint 暴露的 json 中包含了多种属性:

    1. appName: 应用名

    2. logDir: 日志所在目录

    3. logUsePid: 日志文件名是否带上进程id

    4. blockPage: 限流 block 之后跳转的页面

    5. metricsFileSize: metrics 文件的大小

    6. metricsFileCharset: metrics 文件对应的字符集

    7. totalMetricsFileCount: metrics 最多保留的文件数

    8. consoleServer: sentinel dashboard 地址

    9. clientIp: 客户端 ip

    10. heartbeatIntervalMs: 客户端跟 dashboard 的心跳间隔时间

    11. clientPort: 客户端需要暴露的端口跟 dashboard 进行交互

    12. coldFactor: 冷启动因子

    13. filter: CommonFilter 相关的属性, 比如 order, urlPatterns 以及 enable

    14. datasource: 客户端配置的数据源信息

    15. rules: 客户端生效的规则,内部含有 flowRules, degradeRules, systemRules, authorityRule, paramFlowRule

    这是 Endpoint 暴露的 json 示例:

    {
        "blockPage": null,
        "appName": "sentinel-example",
        "consoleServer": "localhost:8080",
        "coldFactor": "3",
        "rules": {
            "flowRules": [{
                "resource": "GET:http://www.taobao.com",
                "limitApp": "default",
                "grade": 1,
                "count": 0.0,
                "strategy": 0,
                "refResource": null,
                "controlBehavior": 0,
                "warmUpPeriodSec": 10,
                "maxQueueingTimeMs": 500,
                "clusterMode": false,
                "clusterConfig": null
            }, {
                "resource": "/test",
                "limitApp": "default",
                "grade": 1,
                "count": 0.0,
                "strategy": 0,
                "refResource": null,
                "controlBehavior": 0,
                "warmUpPeriodSec": 10,
                "maxQueueingTimeMs": 500,
                "clusterMode": false,
                "clusterConfig": null
            }, {
                "resource": "/hello",
                "limitApp": "default",
                "grade": 1,
                "count": 1.0,
                "strategy": 0,
                "refResource": null,
                "controlBehavior": 0,
                "warmUpPeriodSec": 10,
                "maxQueueingTimeMs": 500,
                "clusterMode": false,
                "clusterConfig": null
            }]
        },
        "metricsFileCharset": "UTF-8",
        "filter": {
            "order": -2147483648,
            "urlPatterns": ["/*"],
            "enabled": true
        },
        "totalMetricsFileCount": 6,
        "datasource": {
            "ds1": {
                "file": {
                    "dataType": "json",
                    "ruleType": "FLOW",
                    "converterClass": null,
                    "file": "...",
                    "charset": "utf-8",
                    "recommendRefreshMs": 3000,
                    "bufSize": 1048576
                },
                "nacos": null,
                "zk": null,
                "apollo": null,
                "redis": null
            }
        },
        "clientIp": "30.5.121.91",
        "clientPort": "8719",
        "logUsePid": false,
        "metricsFileSize": 52428800,
        "logDir": "...",
        "heartbeatIntervalMs": 10000
    }
    

    相关文章

      网友评论

        本文标题:详解微服务之Spring Cloud Alibaba Senti

        本文链接:https://www.haomeiwen.com/subject/mrixmktx.html