1 FlowRuleManager初始化属性
限流规则集合
private static final Map<String, List<FlowRule>> flowRules = new ConcurrentHashMap<String, List<FlowRule>>();
规则加载/更新
// 规则加载/更新器
private static final FlowPropertyListener LISTENER = new FlowPropertyListener();
// 私有内部类实现(策略模式)限流属性更新加载器
private static final class FlowPropertyListener implements PropertyListener<List<FlowRule>> {
@Override
public void configUpdate(List<FlowRule> value) {
Map<String, List<FlowRule>> rules = FlowRuleUtil.buildFlowRuleMap(value);
if (rules != null) {
flowRules.clear();
flowRules.putAll(rules);
}
RecordLog.info("[FlowRuleManager] Flow rules received: " + flowRules);
}
@Override
public void configLoad(List<FlowRule> conf) {
Map<String, List<FlowRule>> rules = FlowRuleUtil.buildFlowRuleMap(conf);
if (rules != null) {
flowRules.clear();
flowRules.putAll(rules);
}
RecordLog.info("[FlowRuleManager] Flow rules loaded: " + flowRules);
}
}
变化规则集合
// 规则更新执行的调用者
private static SentinelProperty<List<FlowRule>> currentProperty = new DynamicSentinelProperty<List<FlowRule>>();
创建一个延迟线程池(数据统计监听器)
@SuppressWarnings("PMD.ThreadPoolCreationRule")
private static final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1,
new NamedThreadFactory("sentinel-metrics-record-task", true));
规则初始化和开启数据统计监听任务
static {
// 设置监听
currentProperty.addListener(LISTENER);
// 每一秒钟调用MetricTimerListener的方法
SCHEDULER.scheduleAtFixedRate(new MetricTimerListener(), 0, 1, TimeUnit.SECONDS);
}
2 限流规则FlowRule加载
一 采用埋点方式手动加载规则
关键代码
flowRuleManager.loadRules(List<FlowRule> rules)
// @loadRules,
将规则更新到flowRules。
二 采用nacos动态推送的模式
关键代码
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSourceHyit<>(nacos.getServerAddr(),
nacos.getGroupId(), nacos.getDataId(),
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
@register2Property
NacosDataSource关键属性configListener重receiveConfigInfo内部调用currentProperty.updateValue(rules),
在NacosDataSource被构建时调用initNacosListener构建configService在构建时初始化NacosConfigService的一些属性
HttpAgent > new MetricsHttpAgent(new ServerHttpAgent(properties))与nacos服务建立http连接进行数据通信
ClientWorker > new ClientWorker(agent, configFilterChainManager, properties)开启一个任务进行nacos规则监听,规则变化进行安全通知,CopyOnWriteArrayList listeners 调用receiveConfigInfo将最新规则更新到flowRules
3 关键代码
register2Property
/**
* 规则动态拉取调用register2Property添加一个规则更新器将规则put到flowRules
* Listen to the {@link SentinelProperty} for {@link FlowRule}s. The property is the source of {@link FlowRule}s.
* Flow rules can also be set by {@link #loadRules(List)} directly.
*
* @param property the property to listen.
*/
public static void register2Property(SentinelProperty<List<FlowRule>> property) {
AssertUtil.notNull(property, "property cannot be null");
synchronized (LISTENER) {
RecordLog.info("[FlowRuleManager] Registering new property to flow rule manager");
currentProperty.removeListener(LISTENER);
//
property.addListener(LISTENER);
currentProperty = property;
}
}
loadRules
/**
* 更新规则信息(补充动态拉取配置会实时调用loadRules方法更新规则NacosDataSource> configListener >receiveConfigInfo)
* Load {@link FlowRule}s, former rules will be replaced.
*
* @param rules new rules to load.
*/
public static void loadRules(List<FlowRule> rules) {
currentProperty.updateValue(rules);
}
getFlowRuleMap
/**
* 获取所有限流规则 在flowSolt中调用进而进行checkFlow(规则遍历) 规则限制
* @return
*/
static Map<String, List<FlowRule>> getFlowRuleMap() {
return flowRules;
}
以上就是FlowRuleManager初始化和规则加载原理,代码很简单,结合注释和sentinel源码很好理解,对内容有什么问题什么问题欢迎评论