🍖平滑热刷新
LiteFlow支持了优雅平滑热刷新的特性。
即你可以在不重启服务的情况下,进行规则的重载。并且在高并发下刷新的时候,正在执行流程的线程是完全平滑的,不会因为刷新的过程而出现中断的现象。
在刷新时,正在执行的流程还是走的旧的流程,刷新好。后续request会自动切换到新的流程。
# 自动刷新的场景
自动刷新包括了规则以及脚本。
如果你使用LiteFlow原生支持的zookeeper,etcd,nacos,apollo等插件(关于如何集成插件,请参考规则文件
这一大章节),不需要你做任何事,只要规则更改之后,会自动热平滑刷新。
如果你是基于本地磁盘规则文件的,并且开启了自动监听设置,那么更改流程后也会自动平滑刷新。关于如何开启自动监听,请参考本地规则文件监听这一章。
如果你使用了LiteFlow原生支持的sql,redis这两个插件,并开启了轮询开关,在你更新了规则或脚本之后,也会自动平滑热刷新。但是受限于轮询间隔时间,会有一定的延时。
# 主动调用代码全量刷新
主动刷新包括了规则以及脚本。
如果你使用了数据库作为规则文件的存储方式,或是你自己实现了自定义配置源,那么LiteFlow还提供了一种基于代码刷新的方式。
你可以在spring容器中拿到FlowExecutor
对象后,调用以下接口:
flowExecutor.reloadRule();
这个方法会按照启动时的方式去拉取你最新的所有规则以及组件配置信息,进行平滑热刷新。
这样调用有以下2点注意事项:
提示
1.这样刷新是全量刷新,不过各位同学不用担心其性能,经测试,LiteFlow框架一秒可以刷新1000条规则左右,这都是一些cpu级别的操作,如果你规则没有上大几千,几w条,那么推荐这种方式。
2.如果你的应用是多节点部署的,必须在每个节点上都要刷新,因为规则是存储在jvm内存里的。这就意味着,如果你把刷新规则做成一个rpc接口(诸如dubbo接口之类的),那么rpc接口只会调用到其中一个节点,也就是说,只会有一个节点的规则会刷新。
正确的做法是:利用mq发一个消息,让各个节点去监听到,进行刷新。
# 单独刷新某一个规则
如果你的规则比较多,成千上万条,又或者你就是不想全量刷新。希望单独刷新某个改动的规则。
那么LiteFlow也提供了相应的方式。
你可以利用以下api来进行刷新:
FlowBus.reloadChain("chain1", "THEN(a, b, c)");
提示
既然是指定刷新,那么必须你要获取到改动的EL内容,然后再利用动态代码构建重新build下就可以了,这种方式会自动替换缓存中已有的规则。这种方式不用在build之前销毁流程。
如果是多服务节点部署的情况下,还是要遵循每个节点要都刷新,上面已经说明具体建议的方式。这里不再赘述。
# 单独刷新某一个决策规则v2.12.2+
如果你使用了决策路由,那么可以通过FlowBus连带决策体一起进行刷新:
FlowBus.reloadChain("chain1", "THEN(a, b, c)", "AND(r1, r2)");
# 单独刷新某一个脚本
如果你想要用代码方式来刷新一个指定的脚本,可以这么做:
FlowBus.reloadScript(nodeId, script);