携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
一、GateWay整合sentinel流控降级详细配置
GateWay整合sentinel的流控降级略有不同,下面就对配置进行配置讲解一下。
1-2、流控配置
1-2-1、间隔配置
以QPS为例,设置对应间隔,就是间隔n秒内允许n个QPS通过。如下为每秒2个QPS
1-2-2、Burst size宽容次数设置
Burst size,就是在设置对应规则之下还允许宽容请求的次数,如下为每秒4次QPS(阈值+Burst size)
1-2-3、针对请求属性设置
勾选针对请求属性,之后就可以对ip、host、header、url参数、cookie进行相关设置
1-2-3-1、Client IP
选择client ip,就可以通过精确、子串(模糊匹配)、正则对IP进行设置,如下:
通过以上设置,就只针对127.0.0.1进行QPS的流控限制,其他IP访问就不进行流控设置。
1-2-3-2、Header
选择Header 之后,就可以配置Header的名称,这样就可以针对Header名称进行流控设置
通过以上配置,只有Header中包含x-request-id并且值为123。每秒请求2次就被流控。
1-2-3-3、Url参数
选择URL参数之后,就可以配置参数名称,这样就可以针对某个参数名称进行流控设置
通过以上配置,只要url中参数name为jony,那么每秒请求2次就会被流控。
1-2-3-4、Cookie
选择cookie之后,就可以配置cookie名称,这样就可以针对某个cookie名称进行流控设置
通过以上配置,只要cookie中的参数token为aaa,那么每秒请求2次就会被流控。
1-2-4、API管理流控
通过GateWay整合sentinel服务之后,就可以对服务进行流控设置,一般情况下GateWay会对多个服务进行配置。为了方便对各个服务接口流控的管理,就可以在API管理里面进行配置
1-2-4-1、设置分组API
通过新增api管理,创建新的api管理,输入api名称,下面可以增加对应的要参与流控的接口地址
新增之后,就可以看到刚刚创建好的api分组中的接口信息
1-2-4-2、给分组设置流控规则
API类型选择API分组,API名称选择刚刚创建好的分组名称
通过以上配置,只要在API分组中的接口,每秒访问超过2个QPS就会被流控。
1-2-5、降级设置
降级设置和之前设置是一样的,如下:
如上配置,统计2秒内至少请求2次有1此请求异常就熔断10秒。
1-3、统一异常处理
在上面测试流控降级的时候,可以看到页面直接返回了流控降级的错误信息,这是非常不友好的,因此就需要对流控降级的异常进行统一处理,这样在后面也方便和前端同学进行对接。
1-3-1、通过代码的方式实现
新增异常处理自动配置类
@Configuration
public class GatewayConfig {
@PostConstruct
public void init(){
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable e) {
Result r = null;
if (e instanceof FlowException) {
r = Result.error(100,"接口限流了");
} else if (e instanceof DegradeException) {
r = Result.error(101,"服务降级了");
} else if (e instanceof ParamFlowException) {
r = Result.error(102,"热点参数限流了");
} else if (e instanceof SystemBlockException) {
r = Result.error(103,"触发系统保护规则了");
} else if (e instanceof AuthorityException) {
r = Result.error(104,"授权规则不通过");
}
return ServerResponse.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(r));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
}
添加返回Result类
public class Result<T> {
private Integer code;
private String msg;
private T data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Result(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Result(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public static Result error(Integer code,String msg){
return new Result(code,msg);
}
}
访问测试,这样就可以返回我们预期的相关信息了,如下:
1-3-2、通过配置文件设置
spring:cloud.sentinel.scg.fallback.mode = response
spring.cloud.sentinel.scg.fallback.response-body = '{"code":403,"mes":"限流了"}'
1-4、通过代码设置流控规则
代码流控规则同样也需要写在自动配置类中,我们就还在上面那个配置类中进行编写
@Configuration
public class GatewayConfig {
@PostConstruct
public void doInit() {
//初始化网关限流规则
initGatewayRules();
//自定义限流异常处理器
initBlockRequestHandler();
}
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
//resource:资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称。
//count:限流阈值
//intervalSec:统计时间窗口,单位是秒,默认是 1 秒。
rules.add(new GatewayFlowRule("order_route")
.setCount(2)
.setIntervalSec(1)
);
rules.add(new GatewayFlowRule("user_service_api")
.setCount(2)
.setIntervalSec(1)
);
// 加载网关规则
GatewayRuleManager.loadRules(rules);
}
public void initBlockRequestHandler(){
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable e) {
Result r = null;
if (e instanceof FlowException) {
r = Result.error(100,"接口限流了");
} else if (e instanceof DegradeException) {
r = Result.error(101,"服务降级了");
} else if (e instanceof ParamFlowException) {
r = Result.error(102,"热点参数限流了");
} else if (e instanceof SystemBlockException) {
r = Result.error(103,"触发系统保护规则了");
} else if (e instanceof AuthorityException) {
r = Result.error(104,"授权规则不通过");
}
return ServerResponse.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(r));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
}
和之前不同的是,在初始化的时候,之前使用FlowRule而GateWay使用GateWayFlowRule
添加网关规则之前使用RuleManager,而GateWay使用GateWayRuleManager.
1-5、GateWay高可用部署
如果担心单台GateWay无法承担服务,就可以通过nginx负载多态GateWay对外提供服务,这样就可以完成GateWay的高可用部署
nginx配置如下: