我在使用Spring Cloud 整合Sentines做限流时,想把规则数据存到Redis中,Sentines官方文档是支持持久化到Redis的,但是我按照官方文档继承AbstractDataSource接口后,不知道该如何调用这个类。
在启动Spring Cloud项目时,应该如何传入Redis Config 参数和redis 的ruleKey,以及如何让我重写的这个类起作用呢?
不用重写AbstractDataSource类,只需要创建一个项目启动类,并使用默认的实现类即可: `package cn.com.bobfintechgateway.sentinel;
import java.util.List;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component;
import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.datasource.ReadableDataSource; import com.alibaba.csp.sentinel.datasource.redis.RedisDataSource; import com.alibaba.csp.sentinel.datasource.redis.config.RedisConnectionConfig; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference;
/**
@project: 北银金科 @description: 客户端在启动时初始化Redis中规则 @Version 1.0.0 @errorcode
错误码: 错误描述
@author
<li>2020-07-17 guopengfei@bobfintech.com.cn Create 1.0
@copyright ©2019-2020 北银金科,版权所有。
*/ @component public class RedisDataSourceConfig implements ApplicationRunner { private static final Logger log = LoggerFactory.getLogger(RedisDataSourceConfig.class);
@value("${spring.redis.host}") public String redisHost;
@value("${spring.redis.port}") public int redisPort;
@value("${spring.redis.password}") public String redisPass;
@value("${spring.redis.database}") public Integer database;
//限流规则key前缀 public final String RULE_FLOW = "sentinel_rule_flow_"; public final String RULE_FLOW_CHANNEL = "sentinel_rule_flow_channel";
//降级规则key前缀 // public final String RULE_DEGRADE = "sentinel_rule_degrade_"; // public final String RULE_DEGRADE_CHANNEL = "sentinel_rule_degrade_channel";
//系统规则key前缀 // public final String RULE_SYSTEM = "sentinel_rule_system_"; // public final String RULE_SYSTEM_CHANNEL = "sentinel_rule_system_channel";
/**
ApplicationRunner
该接口的方法会在服务启动之后被立即执行
主要用来做一些初始化的工作
但是该方法的运行是在SpringApplication.run(…) 执行完毕之前执行 */ @OverRide public void run(ApplicationArguments args) { log.info("执行sentinel规则初始化 start >>>>>>>>>>>>>"); RedisConnectionConfig config = RedisConnectionConfig.builder().withHost(redisHost).withPort(redisPort) .withPassword(redisPass).withDatabase(database).build(); Converter<String, List> parser = source -> JSON.parseObject(source, new TypeReference() {});
ReadableDataSource<String, List> redisDataSource = new RedisDataSource<>(config, RULE_FLOW, RULE_FLOW_CHANNEL, parser); FlowRuleManager.register2Property(redisDataSource.getProperty()); log.info("执行sentinel规则初始化 end >>>>>>>>>>>>>");
// Converter<String, List> parserDegrade = source -> JSON.parseObject(source, // new TypeReference() { // }); // ReadableDataSource<String, List> redisDataSourceDegrade = new // RedisDataSource<>(config, RULE_DEGRADE + SentinelConfig.getAppName(), // RULE_DEGRADE_CHANNEL, parserDegrade); // DegradeRuleManager.register2Property(redisDataSourceDegrade.getProperty());
// Converter<String, List> parserSystem = source -> JSON.parseObject(source, new // TypeReference() { // }); // ReadableDataSource<String, List> redisDataSourceSystem = new // RedisDataSource<>(config, RULE_SYSTEM + SentinelConfig.getAppName(), RULE_SYSTEM_CHANNEL, // parserSystem); // SystemRuleManager.register2Property(redisDataSourceSystem.getProperty()); log.info(">>>>>>>>>执行sentinel规则初始化 end。。。"); }
}` 原提问者GitHub用户wangmingweikong
我改为拉取模式后也没有效过;我的做法是在sentinel-dashboard 加两个接口,然后client 启动时候去调这两个接口,让服务端主动推送过来(当然我还加了延迟,让client与server通信后才发起请求)。
原回答者GitHub用户keybersan
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
阿里云拥有国内全面的云原生产品技术以及大规模的云原生应用实践,通过全面容器化、核心技术互联网化、应用 Serverless 化三大范式,助力制造业企业高效上云,实现系统稳定、应用敏捷智能。拥抱云原生,让创新无处不在。