Sentinel - 流量控制

1. 准备

下载链接:https://linta0.lanzout.com/iKoau06h7s8h
密码:an8j

启动方法:进入cmd模式,接着在cmd中进入下载后的文件夹,然后输入下面的指令

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

注意:8898是自己指定的端口,可以按照自己的需求进行指定

本次的SpringBoot版本为: 2.2.5.RELEASE
SpringCloud Alibaba版本为: 2.2.1.RELEASE

2. 公共返回值准备

导入依赖

<dependency>
	<groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

说明:

  • 在项目中,基本上都会定义一个公共的返回值类型。前端向后端发出的请求,最终都是以公共的返回值类型响应
  • 前端在发生触发流控的规则后,可以编写一个服务降级或服务熔断后的方法,给用户返回一个托底数据。在Sevice层中,每个方法都会有不同的返回值,如果每一个方法都去单独编写一个相对应的降级或熔断的处理方法,那么会有很大的工作量。所以需要有一个公共的返回值,这样所有的方法都可以使用同一个降级或熔断的处理方法
  • 在项目的开发中,理应使用公共的返回值,也可以用枚举编写专门的错误码

服务降级和服务熔断不了解的,可以去看我的另一篇文章:

https://blog.csdn.net/wanzijy/article/details/125041622


公共返回值

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {

    private String code;

    private String msg;

    private T data;

}

公共返回值相关方法

public class ResultUtil {

    public static<T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode("200");
        result.setMsg("success");
        result.setData(data);
        return result;
    }

    public static<T> Result<T> success() {
        Result<T> result = new Result<>();
        result.setCode("200");
        result.setMsg("success");
        return result;
    }

    public static<T> Result<T> success(String msg, T data) {
        Result<T> result = new Result<>();
        result.setCode("200");
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    public static<T> Result<T> success(String msg) {
        Result<T> result = new Result<>();
        result.setCode("200");
        result.setMsg(msg);
        return result;
    }

    public static<T> Result<T> fail(String code, String msg) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMsg(msg);
        result.setData(null);
        return result;
    }

    public static<T> Result<T> fail() {
        Result<T> result = new Result<>();
        result.setCode("500");
        result.setMsg("系统异常");
        result.setData(null);
        return result;
    }

    public static<T> Result<T> fail(T data) {
        Result<T> result = new Result<>();
        result.setData(null);
        return result;
    }

    public static<T> Result<T> fail(ResultEnum resultEnum) {
        Result<T> result = new Result<>();
        result.setCode(resultEnum.getCode());
        result.setMsg(resultEnum.getMsg());
        result.setData(null);
        return result;
    }

}

2. SpringBoot项目集成

导入依赖

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

2.1 注解方式

2.1.1 配置文件

spring:
  cloud:
    sentinel:
      enabled: true
      eager: true
      transport:
        port: 8719
        dashboard: localhost:8898

注意:

  • 上面代码中“port: 8719”,不能更改
  • dashboard: localhost:8898”,这里的端口号要和启动时指定的端口号一致

2.1.2 使用举例

在Controller方法对应的Service方法的头上加上 @SentinelResource 注解,然后再编写相对应的方法,如下:(下面的方法是用来举例)

@SentinelResource(value = "selectListById",
                        blockHandler = "selectListByIdBlockHandle",
                        fallback = "selectListByIdFallback"
    )
public Result selectListById(Integer id) {
	return ResultUtil.success("请求成功");
 }

/**
	* 服务降级后所调用的方法
	* @param id
	* @param exception
	* @return
*/
public Result selectListByIdBlockHandle(Integer id, BlockException exception) {
	exception.printStackTrace();
	return ResultUtil.fail("服务器繁忙,请稍后再试");
}

/**
	* 服务熔断后所调用的方法
	* @param id
	* @param throwable
	* @return
*/
public Result selectListByIdFallback(Integer id, Throwable throwable) {
	System.out.println("请求异常,异常信息如下:" + throwable);
	return ResultUtil.fail("服务器错误,请稍后再试");
}

@SentinelResource注解说明:

  • 这个注解可以放在任何位置,可以是一行代码,一个变量,或者是一个方法
  • value:资源名称,必需的
  • blockHandler:方法被限流后触发的方法,参数最后多一个 BlockException,其余于原函数一致
  • fallback:方法被熔断后执行的方法,函数签名(返回值,参数,类型)一致,参数可以多加一个 Throwable
  • blockHandler和fallback的方法,都不能是private方法

2.1.3 流控测试

重启项目,进入Sentinel的可视化界面:http://localhost:8898
这里的8898是上面启动时的端口号,首次访问要进行登录。账号和密码都是sentinel
首页
自带

不用关心资源名,主要看我框住的操作

重启项目后,要再一次访问接口,才会在Sentinel中显示出来
资源名是访问该接口的url
在这里插入图片描述


在这里插入图片描述
QPS 单位时间内的请求上限,单位是秒
单机阈值为1的意思是:在1秒钟内,服务器处理的请求只能是1个。超过1个后,会根据流控的策略(流控效果)进行相对应的处理

点击“新增”后,可以去项目中快速的多次请求该接口
因为我是使用了公共的返回值,那么前端也应该有相对应的方法去接收和解析该公共返回值
当前端解析,发现返回的状态是“失败”后,就可以通过状态给用户做出相对应的提示
前端的处理方式在文章的后面

2.2 文件方式

像上述的注解方式,给每个方法通过注解编写对应的降级和熔断方法。但是在项目中,会有很多的接口,要是每个接口都去编写方法的话,工作量也会很大
而且像上述在可视化界面添加的流控规则,是保存在内存里的,项目重启后会消失。所以需要一种可持久化存储的方式

2.2.1 修改配置文件

spring:
  cloud:
    sentinel:
      enabled: true
      eager: true
      transport:
        port: 8719
        dashboard: localhost:8898
      datasource:
        ds1:
          file:
            file: classpath:flowRule.json
            data-type: json
            rule-type: flow

注意:

  • data-type: json”,编写的流控规则保存的文件类型为json文件。拓展一下,用于保存流控规则的地方可以是file(文件),Nacos,ZooKeeper,Apollo,Redis。在这里使用file(文件)
  • file: classpath:flowRule.json”,流控规则的json文件的所在地址

classpath的路径:
在这里插入图片描述

2.2.2 json文件的规则说明和可视化界面的关系

json文件编写示例:
在这里插入图片描述

  • resource:资源名,访问接口的url
  • count:单机阈值
  • grade:保持为1,其他值会把可视化界面中的流控效果和超时时间给隐藏掉
  • limitApp:保持为default,其他值没有太深入摸索,大家可以去了解一下
  • strategy:保持为0,其他值会把编写的规则在可视化界面中隐藏
  • controlBehavior:流控效果。0表示快速失败,1表示Warm Up,2表示排队等待

对应关系:
在这里插入图片描述


重启项目后,进入Sentinel
在这里插入图片描述

2.2.3 流控测试

注意:本次是没有在方法上使用注解和编写相对应的降级和熔断方法,而是直接通过在json文件中编写的流控规则来实现流量的控制

在这里,也是同样将QPS调成1来进行测试。然后快速的多次请求接口,接着去查看浏览器控制台
在这里插入图片描述


这种编写流控规则文件的方式才是比较常用的。同样,前端当解析到429状态码后,也应该有相对应的处理方法,在这里举例说明一下
注意:本次举例使用的是 Vue 和 Axios

export async function request(params) {
    return service({
        url: '请求的url',
        method: 'POST',
        data: params,
        headers: {'Content-type': POST_HEADER_URLENCODED}
    }).then(response => {
        if(response.msg == 'success') {
            return response;
        } else {
            //  请求状态为失败
        }
    }).catch(error => {
        // 状态码除200外的,可以在这里进行处理。比如上面的429
    })
}

上面的请求方式是我封装过的,具体的封装可以去看我的另一篇文章

https://blog.csdn.net/wanzijy/article/details/125113405

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LF3_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值