zoukankan      html  css  js  c++  java
  • [学习]sentinel中的DatatSource(二) WritableDataSource

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

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

    wiki:https://github.com/alibaba/Sentinel/wiki

    FAQ:https://github.com/alibaba/Sentinel/wiki/FAQ

    --------------------------------------------------------------------------------------------------------------------------------------------------------

    [学习]sentinel中的DatatSource(一) ReadableDataSource

    在上一篇中学习了sentinel中的ReadableDataSource,本篇来学习和梳理下WritableDataSource。

    --------------------------------------------------------------------------------------------------------------------------------------------------------

    WritableDataSource顾名思义,是可写的数据源,在sentinel-datasource-extension模块下,com.alibaba.csp.sentinel.datasource包:

    接口有两个方法:

    write是将数据写到数据源中,进行保存;

    close是关闭datasource相关的资源。

    该包下提供了一个实现类,FileWritableDataSource,使用文件作为数据源。

    先看属性,定义了

    configEncoder用于将T类型转换为String类型;

    file用于确定数据源文件;

    charset字符集用于区分编码格式,默认是UTF-8;

    lock用户写文件时加锁,避免并发写问题;

    接着是构造函数,可以看到提供了3种重载来方便构造;

    在最后实际调用的构造函数中,首先验证了参数合法性,包括:文件非空、不是目录、转换器和字符集非空;然后将参数保存在类的属性中;

    最后是实现WritableDataSource接口的两个方法:

    write方法首先通过lock加锁,调用转换器configEncoder的convert方法将T类型转换为String,再调用java io将String写入文件,最后释放锁;

    close方法中,因没有释放的资源,不作任何处理。

    在IDEA里,按住Ctrl键,点击FileWritableDataSource<T>类名,发现FileDataSourceInit类用到了它

    该类位于sentinel-demo模块下的sentinel-demo-dynamic-file-rule,是一个FileDatasource的demo演示:

    我们看到FileDataSourceInit实现了InitFunc接口,这是Sentinel 的 InitFunc SPI 扩展接口。

    参考:https://github.com/alibaba/Sentinel/wiki/动态规则扩展

    看代码中如何构造FileWritableDataSource的:

    flowRulePath是流控规则文件的路径;

    encodeJson是前文提到的转换器,这里用了jdk1.8双冒号的语法,使用用fastjson提供的静态方法JSON.toJSONString将List<Rule>转换为String;

    注意到,构造好WritableDataSource后,用WritableDataSourceRegistry.registerFlowDataSource(wds)进行了注册;

    WritableDataSourceRegistry类位于sentinel-transport-common模块里,里面保存了flow、degrade、system、authority四种规则的WritableDataSource,并提供了注册(register)和获取(get)的静态方法;

    同样可以使用刚才Ctrl+左键的方式继续跟下去,找到它的调用。限于篇幅就暂不展开了。有兴趣的读者可以试试。

    WritableDataSource用于写规则数据至数据源,跟sentinel-dashborad结合使用。

    以流控规则为例,数据流转大致如下:

    1. 在sentinel-dashboard界面中新增、修改、删除流控规则

    2.dashborad中FlowController接收前端界面请求,先调用InMemFlowRuleStore的repository将内存中的数据更新,然后用SentinelApiClient通过http请求的方式与sentinel客户端(接入sentinel的应用)进行交互

       http://ip:port/setRulesPath?type=flowRuleType&data=xxx

    3.sentinel客户端的ModifyRulesCommandHandler处理请求,通过FlowRuleManager.loadRules(flowRules)重新加载规则,再调用已注册的WritableDataSource的write方法,将规则数据写至数据源

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    我们来看看FileDataSource的demo。

    FileDataSourceDemo类listenRules方法,构造了3种规则的FileRefreshableDataSource。

    FlowQpsRunner类中的资源名称为"abc",

    在FlowRule.json文件中有一条该资源的流控规则:

    可以看到是controlBehavior=0默认快速失败方式,grade=1的QPS方法,count=20.0。 该规则表示超过20QPS/秒进行快速失败限流。

    运行FileDataSourceDemo类的main方法:

    可以看到,通过的qps大致在20左右。

    前文提到FileWritableDataSource在FileDataSourceInit类中构造。demo中使用了FileRefreshableDataSource读取规则。

    我们来把FileWritableDataSource用起来试试。

    参考官方文档,在demo工程的resources目录下,增加META-INF/services目录结构,增加com.alibaba.csp.sentinel.init.InitFunc文件 // 可以从sentinel-transport-simple-http模块中的resources目录拷贝

    文件内容为com.alibaba.csp.sentinel.demo.file.rule.FileDataSourceInit

    因FileDataSourceInit中已经有ReadableDataSource和WritableDataSource构造了,因此我们将FileDataSourceDemo中加载规则的代码注释掉;

    增加启动参数-Dproject.name=FileDataSourceDemo -Dcsp.sentinel.dashboard.server=localhost:8080;

    把dashboard先启起来;

    demo中的FlowQpsRunner类,运行是100秒,为了有更充裕的时间观察、debug而程序不退出,我们把它改大一点:

    FileDataSourceInit加载的文件路径是用户目录下的/sentinel/rules/flowRule.json

    因此我们把目录结构按此建好,拷贝resources下的FlowRule.json文件过去

    然后运行FileDataSourceDemo,启动后观察console输出:

    由于FlowRule.json文件中abc资源的count=20,可以看到pass的qps在20左右;

    浏览器打开控制台http://localhost:8080,在机器列表菜单下,可以看到应用已经在列表中显示

    点击流控规则,

    可以看到资源abc的规则阈值设置为20,点击编辑把阈值改成5,点保存;

    再观察console的输出:

    pass的qps已经从20,降到了5左右;

    打开用户目录下的/sentinel/rules/flowRule.json文件,可以看到json中的abc资源的count已变成了5;

    由此可见,FileWritableDataSource是生效了的;

    并且这种方式结合控制台可以很方便的在界面配置规则,并持久化到文件。

    打开用户目录/logs/csp中的最近修改的record.log.pidxxxx文件:

    2018-09-13 13:13:25 [FlowRuleManager] Flow rules received: {abc1=[FlowRule{resource=abc1, limitApp=default, grade=1, count=20.0, strategy=0, refResource=null, controlBehavior=0, warmUpPeriodSec=10, maxQueueingTimeMs=500, controller=com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController@301ad2}], abc=[FlowRule{resource=abc, limitApp=default, grade=1, count=5.0, strategy=0, refResource=null, controlBehavior=0, warmUpPeriodSec=10, maxQueueingTimeMs=500, controller=com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController@150daa0}]}
    2018-09-13 13:13:25 [FileWritableDataSource] Writing to file C:Usersfivesentinel ulesflowRule.json: [{"controlBehavior":0,"count":20.0,"grade":1,"limitApp":"default","maxQueueingTimeMs":500,"resource":"abc1","strategy":0,"warmUpPeriodSec":10},{"controlBehavior":0,"count":5.0,"grade":1,"limitApp":"default","maxQueueingTimeMs":500,"resource":"abc","strategy":0,"warmUpPeriodSec":10}]

    看到修改的规则已被FlowRuleManager重新加载,并且通过FileWritableDataSource写至到了flowRule.json文件:)

    --------------------------------------------------------------------------------------------------------------------------------------------------------

    总结:

    1. WritableDataSource提供了我们将sentinel内存中规则写回数据源的接口,控制台编辑规则时,除了通过http方式更新sentinel客户端的规则,还会调用WritableDataSourceRegistry注册的WritableDataSource的write方法;

    2. 如Jdbc数据库、File文件等可写入的数据源,实现定制的WritableDataSource接口,可以方便我们配合控制台界面来配置规则;

    3. 不同类型的数据源,根据Pull、Push模式,对控制台、ReadableDataSource、WritableDataSource可根据需要进行不同的定制扩展。

    --------------------------------------------------------------------------------------------------------------------------------------------------------

    思考:

    1.WritableDataSource的write默认是全量更新数据,单个应用规则多时可能有性能问题,考虑如何区分出有变动的增量规则,将增量数据写入数据源;

    2.sentinel的控制台界面,规则是按应用、ip、端口来单独配置的,设计持久化结构时需要考虑。

     --------------------------------------------------------------------------------------------------------------------------------------------------------

    参考:

    https://github.com/alibaba/Sentinel/wiki/动态规则扩展

    https://github.com/alibaba/Sentinel/wiki/控制台

  • 相关阅读:
    时期日期相关JS
    linq版本不同,升级后的问题
    Andriod小型管理系统(Activity,SQLite库操作,ListView操作)(源代码下载)
    FLASH所支持的HTML标记[转]
    从尘埃里开出花
    鴻海董事長郭台銘先生的話
    一日 :)
    今天休息,一个人在城市里看云 : (
    微软面试题——海盗分金币:)
    我QQ史上见过的最自恋,最芙蓉,最皮厚的人:口水弟: )
  • 原文地址:https://www.cnblogs.com/cdfive2018/p/9639326.html
Copyright © 2011-2022 走看看