轮询模式配置
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
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内的field为chainId,value为单纯的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:if_script:脚本组件3 | if(a > 100){return true;}else{return false;} |
关于脚本类型,可以参照定义脚本组件这一章节。
# 自动刷新
使用了此Redis配置源插件的轮询模式,凡是在配置的Redis键内的数据改动,会依据设定的轮询参数定期拉取并更新数据,你无需做任何事情。
# 模式优缺点
根据工作原理,轮询模式在性能方面做出了权衡:
【优势】
- 能做到按需拉取真实数据,缓存占用空间小;
- 计算脚本预先缓存到服务端,不影响Redis服务端性能;
- 基于Redis原生Hash结构存储,可通过任意客户端或命令行操作数据。
【劣势】
- 受轮询间隔限制,数据更新不实时;
- 客户端定时轮询存在性能消耗,但仅做指纹值对比,传输数据量小,实际性能影响很小。
如果对数据数据延迟容忍度高,且希望Redis客户端不受限的情况下,推荐采用轮询模式。
# 小例子
为了让大家能简单上手Redis规则文件的配置和运行,这里有一个小demo,大家可以拉到本地来运行,需要你替换Redis的配置信息。
运行项目前,先读项目里的readme.txt
文件。
https://github.com/bryan31/liteflow-ext-rule-demo