在代码中静态地为Spring Cloud Alibaba Sentinel初始化各种规则不生效。
日志报错为 c.a.c.s.d.SentinelConverter : converter can not convert rules because source is empty。
检查bootstrap.yml中的数据源配置,配置正确无误,如下:
spring:
cloud:
sentinel:
transport:
port: 8719 # Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个端口的 Http Server 接收
dashboard: 192.168.20.134:8100
datasource:
flow:
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
dataId: ${spring.application.name}-flow-rules
groupId: DEFAULT_GROUP
namespace: ${spring.cloud.nacos.discovery.namespace}
data-type: json
rule-type: flow
尝试更换JDK版本也无法解决问题,依旧报错。查阅官方文档,根据官方所提供的代码配置数据源,问题解决。
官方示例代码片段如下:
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, remoteAddress);
properties.put(PropertyKeyConst.NAMESPACE, NACOS_NAMESPACE_ID);
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(properties, groupId, dataId,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
新建配置类:
@Configuration
public class NacosDataSourceConfig {
public static String REMOTE_ADDRESS;
public static String GROUP_ID;
public static String DATA_ID;
public static String NACOS_NAMESPACE_ID;
// nacos server ip
@Value("${server-addr}")
public void setRemoteAddress(String remoteAddress) {
REMOTE_ADDRESS = remoteAddress;
}
// nacos group
@Value("${groupId}")
public void setGroupId(String groupId) {
GROUP_ID = groupId;
}
// nacos dataId
@Value("${dataId}")
public void setDataId(String dataId) {
DATA_ID = dataId;
}
// fill your namespace id,if you want to use namespace. for example: 0f5c7314-4983-4022-ad5a-347de1d1057d,you can get it on nacos's console
@Value("${namespace}")
public void setNacosNamespaceId(String nacosNamespaceId) {
NACOS_NAMESPACE_ID = nacosNamespaceId;
}
@Bean
public static ReadableDataSource configNacosDataSource() {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, REMOTE_ADDRESS);
properties.put(PropertyKeyConst.NAMESPACE, NACOS_NAMESPACE_ID);
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(properties, GROUP_ID, DATA_ID,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
return flowRuleDataSource;
}
}
流控规则硬编码的 Controller 的代码如下:
@RestController
@RequestMapping("/code")
public class FlowRuleCodeController {
public final ReadableDataSource<String, List<FlowRule>> flowRuleDataSource;
public FlowRuleCodeController(ReadableDataSource<String, List<FlowRule>> flowRuleDataSource) {
this.flowRuleDataSource = flowRuleDataSource;
}
/**
* <h2>初始化流控规则</h2>
*/
@PostConstruct
public void init() {
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
// 流控规则集合
List<FlowRule> flowRules = new ArrayList<>();
// 创建流控规则
FlowRule flowRule = new FlowRule();
// 设置流控规则 QPS, 限流阈值类型 (QPS, 并发线程数)
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 流量控制手段
flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
// 设置受保护的资源
flowRule.setResource("flowRuleCode");
// 设置受保护的资源的阈值
flowRule.setCount(1);
flowRules.add(flowRule);
// 加载配置好的规则
FlowRuleManager.loadRules(flowRules);
}
}
再次运行工程,成功新建初始化规则。
参考issue:
https://github.com/alibaba/Sentinel/issues/2267