sentinel中的DatatSource学习

sentinel是今年阿里开源的高可用防护的流量管理框架。

git地址:https://github.com/alibaba/Sentinel

本文对其中的DataSource扩展进行学习和总结。

sentinel-datasource-extension模块,在sentinel-extension模块下,如下图:

 sentinel-datasource-extension模块主要定义了datasource扩展相关的接口,见下图:

其中,FileRefreshableDataSource、FileWritableDataSource是基于文件的DataSource的实现;

此外官方还提供了zookeeper、nacos、apolo的3个DataSource实现,参见上图的sentinel-datasource-zookeeper、sentinel-datasource-nacos、sentinel-datasource-apollo的3个模块;

首先,我们来看下sentinel-datasource-extension模块吧,先看下接口和类图结构;

在IDEA里,选中com.alibaba.csp.sentinel.datasource包下所有类和接口,右键->Diagrams->Show Diagram(Ctrl+Alt+Shift+U):

可以看到,顶层有3个接口,两个DataSource,一个Converter;

顾名思义,ReadableDataSource表示读的数据源,WriteableDataSource表示写的数据源,Converter表示转换器接口;

一个个看:)

ReadableDataSource<S, T>:这是个泛型接口,其实注释很清楚了,S、T分别代码来源和结果,一般是把某个数据来源对象转换成Sentinel的Rule类,比如String->List<FlowRule>;

接口定义了4个方法:

1.T loadConfig() 从数据源中读取数据,返回T类型数据;

   后面会看到,其实该方法实现通常是2步

   S readSource(); // 调下面的readSource接口读取

   T convert(S source); // 通过Converter<S, T>接口转换

2.S readSource() 从数据源中读取数据,返回S类型数据;

   读取数据跟具体的数据源有关,需要数据源相关的api包或client;

   比如从文件中读数据,通过java.io、java.nio包;

          从zookeeper读取,通过org.apache.curator client api;

      

    读数据又分为拉模式、推模式,参考sentinel官方的wiki,动态规则扩展:https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95

    拉模式:继承AutoRefreshDataSource抽象类,在readSource()中实现从数据源读取数据;

    推模式:继承AbstractDataSource抽象类,在构造函数中添加数据源变动的监听器,在readSource()中实现从数据源读取数据;

    注:继承这两个抽象类是推荐的一种简单方式,但不是强制;

3.SentinelProperty<T> getProperty() 返回SentielProperty,注意是<T>类型

   SentinelProperty<T>是一个泛型接口,在sentinel-core模块的property包下

4.void close() 关闭数据源,一般是指释放资源,比如文件类型数据源关闭文件

既然关键的接口,其中一个方法返回SentinelProperty<T>,那我们先去core看看,该接口和相关的实现类。

先查看接口和类图结构。同样方法,选中property包下所有类和接口,右键->Diagrams->Show Diagram(Ctrl+Alt+Shift+U):

顶层有2个接口,看名称PropertyListener可能跟SentinelProperty的监听有关。

先看SentinelProperty接口

有3个方法,看名称感觉有点像观察者模式中的监听器。

接着,我们看下它的2个实现类

NoOpSentinelProperty类方法实现为空,从名称也看得出,它不作任何操作;对着类名按住Crtl+鼠标左键,

发现只有EmptyDataSource类用到了NoOpSentinelProperty,看注释和方法,了解到这是一个空的DataSource实现,用于设置默认配置。

接着,我们重点关注SentinelProperty<T>接口的另一个实现,DynamicSentinelProperty<T>

可以看到,DynamicSentinelProperty<T>定义了2个属性,

Set<PropertyListener<T>> listeners用于保存属性监听器,注意PropertyListener<T>是接口类型;

T value 用于存值;

观察addListener、removeListener方法,分别是往Set<PropertyListener<T>> listeners添加和删除监听器;

只是addListener方法添加了监听器后,调用了添加的那个监听器的listener.configLoad(value)方法,用于监听器处理第一次加载的回调

在实现的void updateValue(T newValue)方法中,首先通过isEqual(value, newValue)方法,判断了新值和旧值是否相同,

如果相同,不作处理直接返回;

如果不同,首先用RecordLog.info方法记1条日志信息;

将新值赋给value,遍历监听器集合,调用回调方法listener.configUpdate(newValue);// 看到这里就清楚这是典型的观察者模式

此外,DynamicSentinelProperty还提供一个public方法close用户清空监听器集合;

猜你喜欢

转载自www.cnblogs.com/cdfive2018/p/9614314.html
今日推荐