资讯详情

SpringCloud 2020版本教程3:使用sentinel作为熔断器

什么是sentinel

Sentinel,中文翻译为哨兵,为微服务提供流量控制和熔断降级功能Hystrix同样的功能可以有效解决微服务调用产生的雪崩效应,为微服务系统提供稳定的解决方案。随着Hytrxi进入维修期,不再提供新功能,Sentinel这是一个很好的替代方案。通常情况,Hystrix利用线程池隔离服务调用,Sentinel与用户线程隔离接口相比,Hystrxi是服务级隔离,Sentinel提供接口级隔离,Sentinel隔离等级更精细,另外Sentinel与用户线程直接限制相比,Hystrix隔离线程池,减少线程切换成本。另外Sentinel的DashBoard在线改变限流规则提供配置,更加优化。

介绍官方文件,Sentinel 具有以下特点:

下载sentinel dashboard

Sentinel dashboard提供机器发现、单机资源实时监控、集群资源实时监控、集群资源量级控制台。您只需要简单地配置应用程序就可以使用这些功能。

下载最新的sentinel dashboard,下载地址为https://github.com/alibaba/Sentinel/releases

启动端口为8748,启动命令如下:

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

改造consumer

本教程的例子是基于上一节的例子。

在consumer的pom文件加上spring cloud sentinel依赖如下:

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

配置文件application.yml添加以下配置:

server:   port: 8763  spring:   application:     name: consumer    cloud:     nacos:       discovery:         server-addr: 127.0.0.1:8848     sentinel:       transport:         port: 18763         dashboard: localhost:8748  feign:   sentinel:     enabled: true      

通过feign.sentinel.enable开启Feign和sentinel自动适配sentinel的dashboard的地址。

通过如此简单的配置,Feign和sentinel配置好了。启动三个项目。provider\consumer\gateway。

多次访问浏览器http://localhost:5000/consumer/hi-feign

访问浏览器localhost:8748,登陆sentinel登录用户为的控制台sentinel,密码为sentinel。

consumer服务的/hi-feign接口,增加流控规则:

qps一、快速访问http://localhost:5000/consumer/hi-feign,会有失败。

在Spring cloud gateway上使用sentinel

Spring cloud gateway已经适配了sentinel,在gatewayg工程的pom文件加相关依赖:

     <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> 

在配置文件application.yml上加上sentinel dashboard的配置:

spring:   cloud:     sentinel:      transport:        port: 15000        dashboard: localhost:8748  

创建网关分组和网关限流规则,代码如下,参考https://github.com/alibaba/Sentinel/wiki/网关限流

@Configuration public class GatewayConfiguration {      private final List<ViewResolver> viewResolvers;     private final ServerCodecConfigurer serverCodecConfigurer;      public GatewayConfiguration(ObjectProvider<List<ViewResolver>> 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(-1)     public GlobalFilter sentinelGatewayFilter() {         return new SentinelGatewayFilter();     }      @PostConstruct     public void doInit() {         initCustomizedApis();         initGatewayRules();     }      private void initCustomizedApis() {         Set<ApiDefinition> definitions = new HahSet<>();
        ApiDefinition api1 = new ApiDefinition("consumer")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {
    
       {

                    add(new ApiPathPredicateItem().setPattern("/consumer/**")
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});
        ApiDefinition api2 = new ApiDefinition("provider")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {
    
       {
                    add(new ApiPathPredicateItem().setPattern("/provider/**")
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});
        definitions.add(api1);
        definitions.add(api2);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }

    private void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        rules.add(new GatewayFlowRule("consumer")
                .setCount(10)
                .setIntervalSec(1)
        );
        rules.add(new GatewayFlowRule("consumer")
                .setCount(2)
                .setIntervalSec(2)
                .setBurst(2)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP)
                )
        );
        rules.add(new GatewayFlowRule("provider")
                .setCount(10)
                .setIntervalSec(1)
                .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
                .setMaxQueueingTimeoutMs(600)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER)
                        .setFieldName("X-Sentinel-Flag")
                )
        );
        rules.add(new GatewayFlowRule("provider")
                .setCount(1)
                .setIntervalSec(1)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                        .setFieldName("pa")
                )
        );
        rules.add(new GatewayFlowRule("provider")
                .setCount(2)
                .setIntervalSec(30)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                        .setFieldName("type")
                        .setPattern("warn")
                        .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_CONTAINS)
                )
        );

        rules.add(new GatewayFlowRule("provider")
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                .setCount(5)
                .setIntervalSec(1)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                        .setFieldName("pn")
                )
        );
        GatewayRuleManager.loadRules(rules);
    }
}

在sentinel 控制台为gateway创建一个限流规则,如下:

流控规则为qps=1,快速访问http://localhost:5000/consumer/hi-feign,在qps>1的情况下,会报以下的错误:

Blocked by Sentinel: FlowException

可见sentinel的配置已经生效,更多sentinel教程,请关注fangzhipeng.com网站。

参考文档

https://www.fangzhipeng.com/springcloud/2019/06/02/sc-sentinel.html

https://github.com/alibaba/Sentinel/releases

https://github.com/alibaba/Sentinel/tree/master/sentinel-dashboard

https://github.com/spring-cloud-incubator/spring-cloud-alibaba/wiki/Sentinel

https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0

源码下载

https://github.com/forezp/SpringCloudLearning/tree/master/sc-2020-chapter3

标签: 久茂熔体变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台