[学习]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:\Users\five\sentinel\rules\flowRule.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/控制台
[学习]sentinel中的DatatSource(二) WritableDataSource的更多相关文章
- [学习]sentinel中的DatatSource(一) ReadableDataSource
sentinel是今年阿里开源的高可用防护的流量管理框架. git地址:https://github.com/alibaba/Sentinel wiki:https://github.com/alib ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二) 代码工程地址: https:/ ...
- 一起学习PHP中GD库的使用(二)
在日常的开发过程中,GD 库最常用的功能就是帮我们对图片进行一些处理,当然,除了处理已有的图片之外,它也可以直接来画图,就像我们最常见的图片验证码.今天的内容主要就是和画图有关,所以最后我们也会做一个 ...
- Redis Sentinel中的机制与原理详解
序言 Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案.实际上这意味着你可以使用Sentinel模式创建一个可以不用人为干预而应对各种故障的Redis部署. 它的主要功能有以 ...
- Android学习开发中如何保持API的兼容
Android学习开发中如何保持API的兼容: 1,采用良好的设计思路 在设计过程中,如果能按照下面的方式来进行设计,会让这个API生命更长久 面向用例的设计,收集用户建议,把自己模拟成用户,保证AP ...
- redis 系列24 哨兵Sentinel (中)
四. 检测下线状态 对于Redis的Sentinel中关于下线有两个不同的概念:(1)主观下线(Subjectively Down, 简称 Sdown) 指的是单个 Sentinel 实例对服务器做出 ...
- JavaScript学习笔记之数组(二)
JavaScript学习笔记之数组(二) 1.['1','2','3'].map(parseInt) 输出什么,为什么? ['1','2','3'].map(parseInt)//[1,NaN,NaN ...
- 学习Spring Boot:(二十五)使用 Redis 实现数据缓存
前言 由于 Ehcache 存在于单个 java 程序的进程中,无法满足多个程序分布式的情况,需要将多个服务器的缓存集中起来进行管理,需要一个缓存的寄存器,这里使用的是 Redis. 正文 当应用程序 ...
- 深度学习课程笔记(十二) Matrix Capsule
深度学习课程笔记(十二) Matrix Capsule with EM Routing 2018-02-02 21:21:09 Paper: https://openreview.net/pdf ...
随机推荐
- 简单SQL注入试探、一
DVWA——简单SQL注入小记 前不久刚开始接触SQL注入,今天来记录一些最近的一些收获和一些SQL注入方面的知识. 主要是基于DVWA这个开源的平台来进行练习. 废话不多说开始解题. 从简单的SQL ...
- 6.B+Tree 检索原理
B+树的创建(索引的创建) 1.比如为phoneNum创建了一个索引,phoneNum这列保存了很多的手机号码 2.索引创建的过程中,会为这些数据进行适当的编码(根据这个数据所在的物理地址),如 36 ...
- 【3】Kafka安装及部署
一.环境准备 Linux操作系统 Java运行环境(1.6或以上) zookeeper 集群环境,可参照Zookeeper集群部署 . 服务器列表: 配置主机名映射. vi /etc/hosts ## ...
- Maven 基础概念
Project:任何你想构建的事务Maven都可以认为它们是工程,这些工程被定义为工程对象模型(project Object Model POM) 一个工程可以依赖其他的工程,一个工程也可以由多个子工 ...
- Python: sqlite3模块
sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块 SQLite 是一个C语言库,它可以提供一种轻量级的基于磁盘的数据库,这种数据库不需要独立的服务器进程,也允许需要使用一种 ...
- Redis数据类型操作说明
List数据操作 lpush 语法:lpush key value [value…] 作用:将一个或多个值 value 插入到列表 key 的表头(最左边),从左边开始加入值,从左到右的顺序依次插入到 ...
- 我对line-height及vertical-align的一点理解
张鑫旭老师在文章<我对CSS vertical-align的一些理解与认识(一)>中提到: vertical-align:middle属性的表现与否,仅仅与其父标签有关,至于我们通常看到的 ...
- 原生XMLHttpRequest (ajax)的简单使用
示例: 第一步:创建XMLHttpRequest对象 var httpxml ; if(window.XMLHttpRequest){ //大多数浏览器 httpxml = new XMLHttpRe ...
- codeblock的一个小问题
也许不叫问题吧,也可能是编译器的特性. 我的codeblock选择的编译器: 编写.cpp文件时,floatl类型输入输出都是 %f,double类型输入只能是 %lf,输出只能是 %f. 但是在co ...
- Luogu P1450 [HAOI2008]硬币购物 背包+容斥原理
考虑如果没有个数的限制,那么就是一个完全背包,所以先跑一个完全背包,求出没有个数限制的方案数即可. 因为有个数的限制,所以容斥一下:没有1个超过限制的方案=至少0个超过限制-至少1个超过限制+至少2个 ...