前言:本文基于您已有基础的可运行的微服务系统,使用了Sping Cloud Alibaba,Gateway,Nacos等;目标实现网关流控类型的限流。
顾名思义限流用于在高并发场景下限制请求流量的进入,保护系统不被冲垮。阿里巴巴的开源sentinel可以通过设置不同种类规则实现对不同的资源的保护。
本文使用的各版本对应关系如下(官方链接:版本对应关系)
2.6.7
2021.0.2
2021.0.4.0
org.springframework.cloud
spring-cloud-starter-gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
com.alibaba.cloud
spring-cloud-alibaba-sentinel-gateway
com.alibaba.csp
sentinel-datasource-nacos
配置Sentinel Starter,必须有spring-cloud-alibaba-sentinel-gateway,spring-cloud-starter-gateway 依赖来让 spring-cloud-alibaba-sentinel-gateway 模块里的 Spring Cloud Gateway 自动化配置类生效。
避坑点1:通过Spring Cloud Alibaba接入sentinel需要将spring.cloud.sentinel.filter.enabled 配置项置为 false(网关流控默认粒度为route和自定义API分组维度,不支持URL粒度)
避坑点2:通过Spring Cloud Alibaba Sentinel 数据源模块,网关流控规则数据源类型是 gw-flow而不是flow
在gatewaymodule中新建application-sentinel.yaml文件
配置规则
spring:
cloud:
sentinel:
enabled: true
datasource:
ds1:
nacos:
server-addr: ${spring.cloud.nacos.config.server-addr}
namespace: ${spring.cloud.nacos.config.namespace}
data-id: ${spring.application.name}-gateway-flow-rules
group-Id: SENTINEL_GROUP
rule-type: gw-flow
data-type: json
ds2:
nacos:
server-addr: ${spring.cloud.nacos.config.server-addr}
namespace: ${spring.cloud.nacos.config.namespace}
data-id: ${spring.application.name}-gateway-api-rules
group-Id: SENTINEL_GROUP
rule-type: gw-api-group
data-type: json
ds3:
nacos:
server-addr: ${spring.cloud.nacos.config.server-addr}
namespace: ${spring.cloud.nacos.config.namespace}
data-id: ${spring.application.name}-degrade-rules
group-Id: SENTINEL_GROUP
rule-type: degrade
data-type: json
ds4:
nacos:
server-addr: ${spring.cloud.nacos.config.server-addr}
namespace: ${spring.cloud.nacos.config.namespace}
data-id: ${spring.application.name}-system-rules
group-Id: SENTINEL_GROUP
rule-type: system
data-type: json
log:
dir: /home/omo/sentinel/logs
# 启用向sentinel发送心跳
eager: true
scg:
fallback:
response-status: 429
mode: response
response-body: '{"code": 429,"message": "前方拥堵,请稍后再试!"}'
1.sentinel dashboard默认会以spring.application.name开头生成规则,ds1、ds2为本次测试的类型
2.data-type为读取数据类型,此处设置为json
3.最后的fallback配置了被限流后的自定义响应
服务和sentinel dashboard之间通信端口配置
spring:
cloud:
sentinel:
transport:
# sentinel控制台地址
dashboard: localhost:8081
# 跟sentinel控制台交流的端口,随意指定一个未使用的端口即可,默认是8719
port: 8719
# Get heartbeat client local ip
clientIp: 127.0.0.1
Sentinel 1.6.3 引入了网关流控控制台的支持,可以直接在 Sentinel 控制台上查看 API Gateway 实时的 route 和自定义 API 分组监控,管理网关规则和 API 分组配置
首先需要下载控制台工程代码,自行修改编译。也可以使用我改造后的工程,开箱即用:sentinel-dashboard-1.8.6,改造后的工程支持多种规则配置管理、规则推送(推送到nacos)
启动前配置nacos地址和命名空间(application.properties)
启动参数配置(IDEA)
-Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=sentinel-dashboard
启动后效果
push模式流程
(下载sentinel dashboard官方版本时需要自行实现,懒人可直接使用上面我提供的改造后版本)
下面列出核心修改点
@Bean
public ConfigService nacosConfigService() throws Exception {
Properties properties = new Properties();
//nacos地址
properties.put(PropertyKeyConst.SERVER_ADDR, nacosAddr);
//namespace为空即为public
properties.put(PropertyKeyConst.NAMESPACE, namespace);
return ConfigFactory.createConfigService(properties);
}
以及对应规则类型的provider和publisher,以GatewayFlowRule举例:
@Component("gatewayFlowRuleNacosPublisher")
public class GatewayFlowRuleNacosPublisher implements DynamicRulePublisher> {
@Autowired
private ConfigService configService;
@Autowired
private Converter, String> converter;
@Override
public void publish(String app, List rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(app + NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, converter.convert(rules));
}
}
@Component("gatewayFlowRuleNacosProvider")
public class GatewayFlowRuleNacosProvider implements DynamicRuleProvider> {
@Autowired
private ConfigService configService;
@Autowired
private Converter> converter;
@Override
public List getRules(String appName) throws Exception {
String rules = configService.getConfig(appName + NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, 3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
(GatewayFlowRuleController中)
引入
@Autowired
@Qualifier("gatewayFlowRuleNacosProvider")
private DynamicRuleProvider> ruleProvider;
@Autowired
@Qualifier("gatewayFlowRuleNacosPublisher")
private DynamicRulePublisher> rulePublisher;
再修改增删改查方法中的实现,具体细节参考:sentinel-dashboard-1.8.6
启动步骤见上面阐述
针对user服务(为你的网关路由配置中的id)配置了QPS=5,流控方式为快速失败的规则
到nacos后台查看规则详情,已同步到nacos
同样在nacos中修改,dashboard也会同步更新,不再演示。 (规则属性含义参考:限流字段)
先配置API分组
再配置规则(下拉选择刚才配置的分组,同样设置QPS=5)
设置测试用例 设置循环10次
测试结果5次成功5次失败,符合预期,大功告成!
可以看到测试报告中对/auth/oms/** 的路径匹配到了且限流可以生效