五小步快速集成使用sentinel限流

2023年 9月 18日 75.0k 0

1、环境和资源准备

sentinel支持许多流控方式,比如:单机限流、熔断降级、集群限流、系统保护规则、黑白名单授权等。

本文介绍如何快速集成使用sentinel,文中以单机限流为例,使用代码而非控制台配置的方式限流。

  • sentinel官网地址:https://sentinelguard.io/zh-cn/index.html
  • github地址:https://github.com/alibaba/Sentinel
  • 本文采用的版本是1.8.0,下载地址:https://github.com/alibaba/Sentinel/releases/tag/v1.8.0
  • sentinel-dashboard下载地址:https://github.com/alibaba/Sentinel/releases/download/v1.8.0/sentinel-dashboard-1.8.0.jar
  • 本文使用的项目地址:https://github.com/yclxiao/spring-sentinel-demo,代码中有一部分使用的是官方demo。

2、启动sentinel-dashboard

从上文地址下载sentinel-dashboard,然后执行命令启动:java -jar sentinel-dashboard-1.8.0.jar

启动完毕后,通过http://localhost:8080/#/dashboard访问dashboard,出现如下界面:

3、项目集成sentinel

项目中集成sentinel分如下5步。

3.1、引入pom



  com.alibaba.csp
  sentinel-core
  1.8.0



  com.alibaba.csp
  sentinel-transport-simple-http
  1.8.0



  com.alibaba.csp
  sentinel-annotation-aspectj
  1.8.0

3.2、增加sentinel-aop

@Configuration
public class AopConfiguration {
    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}

3.3、增加sentinel.properties配置

在application.properties同级目录下,增加sentinel.properties文件,配置内容如下:

# 集成到sentinel的项目名称
project.name=spring-sentinel-demo
# 对应的sentinel-dashboard地址
csp.sentinel.dashboard.server=localhost:8080

同时需要加载sentinel.properties配置,有两种加载方式,选择一种即可,如下:

3.4、设置需要被限流的资源

给需要被限流的资源打上注解@SentinelResource,使用方式如下。

  • 默认情况下,超出配置的流控阈值后,直接抛出 FlowException(BlockException) 异常,可以使用blockHandler自定义。
  • fallback用于配置熔断降级的方法,当发生慢调用、异常数、异常比例数,会调用fallback方法。
  • 可以针对部分异常情况做忽略处理,不再触发熔断降级。
@Service
public class TestServiceImpl implements top.mangod.springsentineldemo.service.TestService {

    @Override
    @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {top.mangod.springsentineldemo.service.ExceptionUtil.class})
    public void test() {
        System.out.println("Test");
    }

    @Override
    @SentinelResource(value = "hello", fallback = "helloFallback")
    public String hello(long s) {
        if (s < 0) {
            throw new IllegalArgumentException("invalid arg");
        }
        return String.format("Hello at %d", s);
    }

    @Override
    @SentinelResource(value = "helloAnother", defaultFallback = "defaultFallback",
        exceptionsToIgnore = {IllegalStateException.class})
    public String helloAnother(String name) {
        if (name == null || "bad".equals(name)) {
            throw new IllegalArgumentException("oops");
        }
        if ("foo".equals(name)) {
            throw new IllegalStateException("oops");
        }
        return "Hello, " + name;
    }

    public String helloFallback(long s, Throwable ex) {
        // Do some log here.
        ex.printStackTrace();
        return "Oops, error occurred at " + s;
    }

    public String defaultFallback() {
        System.out.println("Go to default fallback");
        return "default_fallback";
    }
}

3.5、指定和加载流控规则

文中我使用代码方式制定流控规则,在控制台中也可以直接配置流控规则,为什么不使用控制台方式呢?

如果是类似云原生的部署环境,比如:将spring应用打成docker镜像,然后在部署到Kubernetes中,部署之后Pod地址是会变化。

只要应用的地址变化后,之前的配置就消失了。不可能每次地址变化后都到控制台去重新配置策略,所以需要选择代码方式制定规则。

流控规则一般会有如下几个:

  • 资源限流规则FlowRule
  • 异常熔断降级规则DegradeRule
  • 系统过载保护规则SystemRule
  • 访问黑白名单规则AuthorityRule

控制台设置流控规则,如下:

代码制定和加载流控规则,如下:

public static void main(String[] args) {
    // 加载限流规则
    initSentinelRule();
    SpringApplication.run(SpringSentinelDemoApplication.class, args);
  }

  private static void initSentinelRule() {
    // 资源限流
    FlowRule flowRule = new FlowRule("test")
        .setCount(1)
        .setGrade(RuleConstant.FLOW_GRADE_QPS);
    List list = new ArrayList();
        /*if (method) {
            FlowRule flowRule1 = new FlowRule("test:sayHello(java.lang.String)")
                    .setCount(5)
                    .setGrade(RuleConstant.FLOW_GRADE_QPS);
            list.add(flowRule1);
        }*/
    list.add(flowRule);
    FlowRuleManager.loadRules(list);

    // 异常降级
    /*List DegradeRules = new ArrayList();
    DegradeRule degradeRule = new DegradeRule("");
    degradeRule.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType());
    degradeRule.setCount(0.7); // Threshold is 70% error ratio
    degradeRule.setMinRequestAmount(100)
            .setStatIntervalMs(30000) // 30s
            .setTimeWindow(10);
    DegradeRules.add(degradeRule);
    DegradeRuleManager.loadRules(DegradeRules);*/

    // 系统负载保护
    /*List systemRules = new ArrayList();
    SystemRule systemRule = new SystemRule();
    systemRule.setHighestSystemLoad(10);
    systemRules.add(systemRule);
    SystemRuleManager.loadRules(systemRules);*/
    
    // 黑白名单授权访问
    /*AuthorityRule rule = new AuthorityRule();
    rule.setResource("test");
    rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
    rule.setLimitApp("appA,appB");
    AuthorityRuleManager.loadRules(Collections.singletonList(rule));*/
  }

4、启动测试

项目启动完毕后,访问链接http://localhost:9091/foo,就可以在控制台上看到被限流的资源

在流控规则这里,可以看到上文中在代码里设置的规则:

启动项目后,测试限流效果,如下:

  • 1秒内多次访问http://localhost:9091/foo,可以看到触发了限流异常:
  • 输入http://localhost:9091/foo?t=-1会触发异常。fallback用于配置熔断降级的方法,当发生慢调用、异常数、异常比例数时,会调用fallback方法。图片
  • 输入http://localhost:9091/baz/foo、http://localhost:9091/baz/bad,会分别触发异常和默认fallback。图片
  • 5、总结

    本文主要介绍spring项目如何快速集成sentinel实现系统限流。

    首先启动sentinel-dashboard,然后使用5个简单步骤即可使用sentinel限流。

    在应用server的IP地址频繁变动的场景下,建议使用代码方式限流。

    流控的方式较多,你需要根据自身的业务需求做选择,我一般情况下选择单机流控和系统保护。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论