【SpringCloudAlibaba】怎么使用Sentinel实现流量控制、降级以及热点控制呢

上一篇博客了解了Sentinel是什么,也知道了怎么安装它的控制台。准备工作做好了,那么它该怎么使用呢,它如何和SpringCloud结合使用,实际代码该怎么使用呢?通过这边博客,一步一步的带您熟悉sentinel的使用

我这里新建了一个项目(sentinel-demo)来做测试实现流量控制、降级以及热点控制,在实际运用中,应该是对应到相应的接口上就好了
在这里插入图片描述

一、共同准备

1、启动sentinel的控制台

这次我指定了端口号

java -jar sentinel-dashboard-1.6.3.jar --server.port=8618

2、引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>0.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-alibaba-sentinel</artifactId>
        <version>0.2.2.RELEASE</version>
    </dependency>
</dependencies>

3、编写配置文件

server:
  port: 8061
spring:
  application:
    name: sentinel-demo
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8618
      eager: true

4、编写启动文件

@SpringBootApplication
public class SentineldemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SentineldemoApplication.class,args);
    }
}

5、编写controller

@RestController
public class SentinelController {
	// 相应的接口,后边分别对流量控制,降级服务,热点限流做了详细介绍
}

二、Sentinel实现流量控制

(1)配置文件方式,在项目启动就加载了限流规则,在方法里调用相应规则,就实现限流了

这种方式,在项目启动后,Sentinel控制台的流控规则里就会看到有一条getLimitByConfig的规则

a)编写配置文件

@Component
public class SentinelApplicationRunner implements ApplicationRunner {
    private static final String GETLIMIT_KEY="getLimitByConfig";

    @Override
    public void run(ApplicationArguments args) throws Exception {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource(GETLIMIT_KEY);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 2.
        rule.setCount(2);
        rule.setLimitApp("default");
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}

b)编写controller

@RestController
public class SentinelController {

    private static final String GETLIMIT_KEY="getLimitByConfig";

    /**
     * 限流 使用配置文件的方式
     * @return
     */
    @GetMapping("getLimitByConfig")
    public String getLimitByConfig(){
        Entry entry = null;
        try {
            entry = SphU.entry(GETLIMIT_KEY);
            return "正常调用了方法getLimitByConfig";
        } catch (BlockException e) {
            e.printStackTrace();
            return "getLimitByConfig 接口访问已经达到上限";
        }finally {
            if(entry!=null){
                entry.exit();
            }
        }
    }
}

c)测试

访问接口http://127.0.0.1:8061/getLimitByConfig,可看到这样的效果
在这里插入图片描述

(2)在sentinel控制台添加限流规则,方法达到限流阈值,触发所定义blockHandler的方法

这种方式就是在项目启动后,手动在sentinel控制台添加流控规则

a)编写controller

@RestController
public class SentinelController {
    /**
     * 限流 注解加Sentinel控制台的方式
     * @return
     */
    @SentinelResource(value = "getLimitByConsole",blockHandler = "getLimitQpsException")
    @GetMapping("getLimitByConsole")
    public String getLimitByConsole(){
        return "正常调用了方法getLimitByConsole";
    }
    public String getLimitQpsException(BlockException be){
        return "getLimitByConsole 接口访问已经达到上限了";
    }
}

b)在sentinel控制台添加限流规则

在这里插入图片描述

c)测试

访问接口http://127.0.0.1:8061/getLimitByConsole,可看到如下这样的效果,代表限流成功

如果阈值设置的大,就好刷新的快些,就可以看到访问达到上限的效果了

在这里插入图片描述

三、Sentinel实现降级服务

(1)基于响应时间的

a)编写controller

@RestController
public class SentinelController {
    /**
     * 服务降级 基于响应时间
     *
     * @return
     */
    @SentinelResource(value = "getDowngradeByRt", fallback = "getDowngradeByRtFallBack")
    @GetMapping("getDowngradeByRt")
    public String getDowngradeByRt() {
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "正常执行了接口getDowngradeByRt";
    }

    public String getDowngradeByRtFallBack() {
        return "响应时间长,执行服务降级方法";
    }
}

b)控制台添加降级规则

在这里插入图片描述

c)测试

执行接口http://127.0.0.1:8061/getDowngradeByRt,可看到这样的结果
在这里插入图片描述

(2)基于错误率的

a)编写controller

@RestController
public class SentinelController {
    /**
     * 服务降级 基于错误率
     *
     * @param age
     * @return
     */
    @SentinelResource(value = "getDowngradeByError", fallback = "getDowngradeByErrorFallback")
    @GetMapping("getDowngradeByError")
    public String getDowngradeByError(int age) {
        int j = 1 / age;
        return "正常执行了接口getDowngradeByError";
    }

    public String getDowngradeByErrorFallback(int age) {
        return "错误率太高了,执行降级方法";
    }

}

b)在控制台添加规则

在这里插入图片描述

c)测试

访问接口http://127.0.0.1:8061/getDowngradeByError?age=1和http://127.0.0.1:8061/getDowngradeByError?age=0,可看到这样的效果
在这里插入图片描述

四、Sentinel实现热点限流

(1)用配置文件方式

这种方式就是,配置了热点规则后,达到阈值后调用这个配置里的方法

a)编写controller

@RestController
public class SentinelController {
    /**
     * 热点限流 统一读配置文件
     *
     * @param userId
     * @return
     */
    @SentinelResource(value = "getHotspotByConfig")
    @GetMapping("getHotspotByConfig")
    public String getHotspotByConfig(String userId) {
        return "成功执行了接口getHotspotByConfig";
    }
}

b)编写配置文件

@RestControllerAdvice
public class InterfaceExceptionHandler {
    @ResponseBody
    @ExceptionHandler(ParamFlowException.class)
    public String hotInterfaceException(ParamFlowException efx){
        return "访问频率太高啦";
    }
}

c)控制台添加热点规则

在这里插入图片描述

d)测试

访问接口http://127.0.0.1:8061/getHotspotByConfig?userId=1,可看到这样的效果

在这里插入图片描述

(2)自己配置达到阈值后,调用自己定义的方法

a)编写controller

@RestController
public class SentinelController {
    /**
     * 热点限流 调自己方法
     *
     * @param userId
     * @return
     */
    @SentinelResource(value = "getHotspotBySelf", fallback = "getHotspotFallback")
    @GetMapping("getHotspotBySelf")
    public String getHotspotBySelf(String userId) {
        return "成功执行了接口getHotspotBySelf";
    }

    public String getHotspotFallback(String userId) {
        return "您当前访问频率过高,请稍后重试";
    }
}

b)控制台添加热点规则

添加方式,和上一个一样,只是资源名不同
在这里插入图片描述

c)测试

访问接口http://127.0.0.1:8061/getHotspotBySelf?userId=1,可看到这样的效果
在这里插入图片描述

d)热点限流还可有有例外?

还有,关于这个热点控制,还有个很好玩的,就是可以设置例外呢,也就可以设置某个(或者某几个)参数访问接口的阈值与普通的不一样
例如我就在getHotspotByConfig这个规则里,设置了特殊账号,代表我的第一个参数的参数值如果是888的话限流阈值就不是1了而是10
在这里插入图片描述
比较刷新接口http://127.0.0.1:8061/getHotspotByConfig?userId=888和http://127.0.0.1:8061/getHotspotByConfig?userId=1就可以看到访问的效果不一样了
userId为888的时候相比userId为1的时候访问次数明显要多,达到限流的时间也不一样

看到这样效果,有没有想到一些秒杀活动呢,有没有想到我们为什么抢不到呢?有没有感觉还是挺好玩的。好了,Sentinel的使用就写到这里了,有什么问题,欢迎大家指教

©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页