轮询模式配置
Redis配置源的规则刷新机制默认为轮询模式。
# 工作原理
轮询模式以 定时拉取 的方式进行规则数据刷新。
在拉取方式的具体设计上主要考虑到两个因素。其一,若每次去Redis中拉取规则数据,需要再次解析和编译,会对框架性能造成很大影响; 其二,大部分时间拉取的数据并无变化,无用功较多。
考虑到如上两个问题,轮询模式数据拉取的工作方式设定为:
1、首次在Redis中获取数据后,将数据以KV结构缓存到本地,key为chainId/scriptId (以下简称数据Id),value为数据的指纹值 (SHA-1值)。相较于原始数据,指纹值数据量小,缓存占用空间可忽略不计。
2、此后的每次轮询中,无需拉取全部数据,而是在Redis端调用脚本计算当前数据的指纹值,仅传输数据Id及对应指纹值。
3、将拉取获得的最新指纹值与本地缓存的指纹值对比,对于发生变化的数据,针对性地根据数据Id从Redis中获取最新数据值,更新规则元数据,同时更新本地缓存指纹值。
以上设定中,首次轮询起始时间、轮询时间间隔均可自由配置。
# 配置参数
Redis配置源支持单点和哨兵两种模式。轮询模式下配置参数如下:
liteflow:
rule-source-ext-data-map:
#单点模式配置如下两项
host: 127.0.0.1
port: 6379
#哨兵模式配置如下三项
redisMode: sentinel
masterName: mymaster
sentinelAddress: [127.0.0.1:26389, 127.0.0.1:26379]
#如果你没有用户名或密码可以不配置
username: root
password: 123456
#下面两项可以选配(2.12.2+支持)
connectionPoolSize: 2
connectionMinimumIdleSize: 4
#下面这几项必须得配置
mode: poll
pollingInterval: 60
pollingStartTime: 60
chainDataBase: 1
chainKey: chainKey
#如果你没有脚本组件,以下可以不配置
scriptDataBase: 1
scriptKey: scriptKey
liteflow.rule-source-ext-data={\
\# 单点模式配置如下两项\
"host":"127.0.0.1",\
"port":6379,\
\# 哨兵模式配置如下三项\
"redisMode":"sentinel",\
"masterName":"mymaster",\
"sentinelAddress":["127.0.0.1:26389","127.0.0.1:26379"],\
"username":"root",\
"password":"123456",\
"mode":"poll",\
"pollingInterval":60,\
"pollingStartTime":60,\
"chainDataBase":1,\
"chainKey":"chainKey",\
"scriptDataBase":1,\
"scriptKey":"scriptKey"\
}
// Make sure to add code blocks to your code group
# 配置说明
配置项 | 说明 |
---|---|
redisMode | Redis模式,single为单点,sentinel为哨兵,默认为单点 |
host | 单点模式Redis连接IP地址 |
port | 单点模式Redis连接端口号 |
masterName | 哨兵模式主节点名 |
sentinelAddress | 哨兵模式哨兵节点连接地址 ip:port |
username | Redis的用户名 (Redis 6.0及以上) |
password | Redis的密码 |
mode | 规则刷新模式,poll为轮询,sub/subscribe为订阅,默认为轮询 |
chainDataBase | 规则数据的数据库号 |
chainKey | 规则数据的Redis key名 |
scriptDataBase | 脚本组件的数据库号 |
scriptKey | 脚本组件的Redis key名 |
pollingInterval | 轮询时间间隔(s),默认为60s |
pollingStartTime | 规则配置后首次轮询的起始时间(s),默认为60s |
# 存储数据说明
提示
在轮询模式中,规则和脚本数据均以Redis Hash结构存储,配置项chainKey
和scriptKey
即为该Hash的名字。
你可以在redis UI客户端直接存入数据,如果使用redis client框架以代码的方式存入时,一定要注意编码,比如以Redisson存储规则时,一定要设置Codec
为StringCodec
。
对于规则来说,你在Redis中需要为规则单独创建一个Hash类型的数据,这个Hash内的每个键值对就是一个规则,Hash内的每一个键的格式为:规则ID[:是否启用]
,其中方括号内的为可选项,值为单纯的EL(THEN(a,b,c)
)。
假设你的规则Hash数据键名为:chains
,那么配置形式样例如下:
Redis HashKey:chains | |
---|---|
chain1 | THEN(a, b, c); |
chain2 | IF(x, b).ELIF(y, c).ELSE(d); |
对于脚本来说,Hash中的field有固定格式:脚本组件ID:脚本类型[:脚本名称:脚本语言:是否启用]
,其中方括号内的为可选项。 value为脚本数据
假设你的脚本Hash数据键名为:scripts
,那么配置形式样例如下:
Redis HashKey:scripts | |
---|---|
s1:script:脚本组件1 | defaultContext.setData("s1","hello") |
s2:script:脚本组件2:js | defaultContext.setData("s2","hello") |
s3:boolean_script:脚本组件3 | if(a > 100){return true;}else{return false;} |
关于脚本类型,可以参照定义脚本组件这一章节。
# 自动刷新
使用了此Redis配置源插件的轮询模式,凡是在配置的Redis键内的数据改动,会依据设定的轮询参数定期拉取并更新数据,你无需做任何事情。
# 模式优缺点
根据工作原理,轮询模式在性能方面做出了权衡:
【优势】
- 能做到按需拉取真实数据,缓存占用空间小;
- 计算脚本预先缓存到服务端,不影响Redis服务端性能;
- 基于Redis原生Hash结构存储,可通过任意客户端或命令行操作数据。
【劣势】
- 受轮询间隔限制,数据更新不实时;
- 客户端定时轮询存在性能消耗,但仅做指纹值对比,传输数据量小,实际性能影响很小。
如果对数据数据延迟容忍度高,且希望Redis客户端不受限的情况下,推荐采用轮询模式。
# 脚本key的语言配置
如果你只依赖了一种脚本语言插件包,那么语言这项是不需要配置的。会自动识别的。如果你配置了多语言脚本,那么脚本语言
这一项,是必须要写的。
比如s1:boolean_script:布尔脚本s1:js
。
关于脚本的多语言共存,请参考多脚本语言混合共存这一章。
# 规则的启用关闭和脚本启用关闭v2.12.0+
LiteFlow也支持在Etcd节点上保留数据的同时关闭和启动规则/脚本。
之前说到规则的key的固定格式为规则ID[:是否启用]
,如果配置chain1:false
,那么这个规则就是关闭状态。相当于逻辑删除。
当然如果你只是配置key为chain1
,那么等价于chain1:true
。
对于脚本key来说,固定格式为脚本组件ID:脚本类型[:脚本名称:脚本语言:是否启用]
,如果配置s1:script:脚本s1:groovy:false
,那么这个脚本就是关闭状态,相当于逻辑删除。
如果不配置最后一项,比如s1:script:脚本s1:groovy
,那么等价于s1:script:脚本s1:groovy:true
。
提示
对于规则key或者脚本key来说,一定要以冒号为分隔符对应好位置,如果你想配置是否启动,那么是在第5项,前面4项就必须要写,如果你写成s1:script:脚本s1:false
那将会报错。
# 小例子
为了让大家能简单上手Redis规则文件的配置和运行,这里有一个小demo,大家可以拉到本地来运行,需要你替换Redis的配置信息。
运行项目前,先读项目里的readme.txt
文件。
https://github.com/bryan31/liteflow-ext-rule-demo