个人博客:无奈何杨(wnhyang)
个人语雀:wnhyang
共享语雀:在线知识共享
Github:wnhyang - Overview
参考
在选择使用LiteFlow
之前应该要对其有一些了解,不求熟悉源码,但对于其设计思想还是了解一下的。这将对于后面使用有很大帮助,官方文档和源码都是很好的学习路径哦!
如官网所讲的,为了实现编排,就要消除组件的差异,由此设计了上下文。而使用LiteFlow
完成业务,上下文与组件的设计又是极其的关键。方法论还是交给会写论文的人来吧,我只能提供一些经验之谈。
下面还是通过项目https://github.com/wnhyang/coolGuard/来讲述吧。
明确数据流转
无论做什么都要对业务足够熟悉,尤其是在使用LiteFlow
时更要对数据流转有把控。
官方讲:其实,使用LiteFlow并不一定要承载你的所有的业务。由于LiteFlow的执行是由执行器对象发起,所以它可以承载你业务中间的任何一小段。
所以LiteFlow
可以承接所有业务中间的任何一小段。而至于选择哪一段是使用者决定的,当然我们在选择使用LiteFlow
时当然也是看中了其灵活编排、热刷新等特点,应该也是有些想法的了。
那下面就从LiteFlow
执行器执行开始吧!对应上图服务选择这一步。
初始化上下文
这时还在execute
之外,这一步初始化所有上下文数据,当然使用重载的传入class
的方法也行,初始化参数传入也是可以。
输入处理
到此大致执行了:THEN(a_icn)
,a_icn
表示输入处理组件,用于一些预处理、简单的加工和输入日志打印类工作。
如下,在使用LiteFow
执行器执行时将后面需要使用的上下文作为参数丢给执行器。在下面开始之前需要额外说明一下,虽然上图的整个流程看起来是一部分,但是在实际运行时其实拆分为多个子流程执行的。这一步执行器传入的chainId
是个变量,这也意味着从这里开始就具备可编排的可能了。决策与非决策、批量与非批量、同步与异步、字段解析与不解析,等等。
对于此步骤能想到的是node(系统字段)、node(动态字段)、node(流控降级组件)等之类吧,目标是做ETL
和流量治理一块的,还没想好,所以先搁置一下了。😂😂
普通字段与动态字段
到此大致执行了:THEN(a_in,nf_cn,df_cn)
,项目为了灵活性的数据接入接受参数的为Map<String,Object>
,风险一定会存在,这个应该放在前面的校验上,这里重点讨论的是将输入参数转为系统可识别的系统字段,nf_cn
表示普通字段处理组件,做的事情包括:根据配置将输入参数转为可识别的系统字段,设计的内置字段的解析(身份中、手机号、ip、经纬度等归属地运营商等),这个解析也预留了接口保留其扩展性,后面可以在讲;df_cn
表示动态字段处理组件,普通字段是直接由输入参数转换而来,最多做一下类型判断、小数位数保留等,而动态字段是由普通字段衍生而来,是通过编辑脚本实现的,使用场景很丰富,最简单如取身份证前6位,交易金额是否是5的倍数,都可以。
nf_cn
和df_cn
都只操作accessRequest
输入上下文,解析后的数据也统一设置在accessRequest
里。
指标计算
到此大致执行了:THEN(a_in,nf_cn,df_cn,I_F)
,I_F
不是通用的组件,实际上是一个子流程,表示指标计算,使用了循环编排。大概是这样的FOR(i_fn).parallel(true).DO(i_cn);
,i_fn
表示指标计算循环次数组件,通过拿accessRequest
查询满足本次请求场景的指标集合,然后并行运行这些指标组件i_cn
,其也是个子流程,大概是IF(cond,i_tcn,i_fcn)
,指标组件首先通过cond
条件组件判断是否满足本条指标条件,满足则执行i_tcn
组件计算指标,不满足则执行i_fcn
,最后将结果设置到IndicatorContext
指标上下文中。
策略集/策略/规则
策略集
到此大致执行了:THEN(a_in,nf_cn,df_cn,I_F,ps_cn)
,ps_cn
是策略集组件是编排的关键,默认会有并行执行和串行执行策略集下所有策略,当然后面会加入其他丰富的内容,如:A/BTest、冠军挑战、三方、模型之类的吧,还在构思。所以先占位吧大概是WHEN(e_cn,p_cn.tag("1"),p_cn.tag("2"));
这种的吧。
此时会拿accessRequest
数据,判断执行哪个策略集,每笔请求只能执行一个策略集,然后将数据放在policyContext
策略上下文和EventContext
事件上下文中,之后执行策略集编排的EL
,结束后整理数据再放accessResponse
响应上下文中。
策略
到此还是在:THEN(a_in,nf_cn,df_cn,I_F,ps_cn)
,但执行的是策略集的编排EL
。LiteFlow
的编排特性在这里会有体现,举个例子:一个策略集下有10个策略,每个策略分别对应不同的模式和规则列表,可以在此挑选1、3、4、5作为一类,其他作为一类,在设置分流策略,结果取xxx。
此子流程大概是FOR(p_fn).DO(r_cn).BREAK(p_bn);
和FOR(p_fn).parallel(true).DO(r_cn);
,分别对应串行运行和并行运行,对应着不同的策略模式。p_fn
表示策略循环次数组件,用于确定需要运行哪些规则,p_bn
表示策略停止组件,用于顺序执行规则时满足某些条件停止后续规则执行。这个过程中拿accessRequest
和policyContext
,计算完策略的结果后放policyContext
,最终会有上层策略集将所欲结果按编排放入accessResponse
和EventContext
,就是栈的模式嘛。
规则
到此也还是在:THEN(a_in,nf_cn,df_cn,I_F,ps_cn)
,根据策略模式的不同执行FOR(p_fn).DO(r_cn).BREAK(p_bn);
或FOR(p_fn).parallel(true).DO(r_cn);
,r_cn
表示规则组件也还是子流程,大概是:IF(cond,WHEN(ruleTrue,addTag,addList,sendSms,setFiled),ruleFalse)
,cond
条件组件true
则并行执行ruleTrue
、addTag
、addList
、sendSms
、setFiled
,ruleTrue
表示规则结果用于最终决策,除此之外都是可选项,addTag
表示增加tag
,addList
表示添加名单,sendSms
表示发送消息,setFiled
表示设置字段。这些组件其实应该有更广的应用场景,但目前统一放在规则里,后续可能让其更具灵活性。这个步骤拿accessRequest
和policyContext
,放policyContext
、accessResponse
和EventContext
。
输出处理
到此执行最后一个a_ocn
输出处理组件后所有流程就都结束了,此过程主要是放accessResponse
。
回顾组件和上下文
以上所有仅代表个人目前的一些用法,仅供参考。
在使用LiteFlow
进行规则编排设计时,要明确抽象出组件数据来源和操作数据上下文。数据来源针对的是对execute
执行后依赖的规则上下文或参数里的数据,自己的tag
、data
或者其他的组件自有数据(不管是声明式或非声明式使用的其他Bean
的能力带来的数据)不算。这样的梳理有利于自己对所有组件和上下文的数据把控,不管是分析某个上下文可能存在的并发访问问题,还是对于组件能否正常执行获取到数据,错误回滚都能有一些把控。
组件 | 说明 | 依赖数据对象 | 目标对象 |
---|---|---|---|
e_cn | 空组件 | 无 | 无 |
a_icn | 输出处理组件 | accessRequest | 无 |
a_ocn | 输出处理组件 | accessRequest | accessResponse |
nf_cn | 普通字段组件 | accessRequest | accessRequest |
df_cn | 动态字段组件 | accessRequest | accessRequest |
i_fn | 指标循环组件 | accessRequest | indicatorContext |
i_cn | 指标普通组件 | indicatorContext | 开启子流程 |
i_tcn | 指标true组件 | accessRequest,indicatorContext | indicatorContext |
i_fcn | 指标false组件 | accessRequest,indicatorContext | indicatorContext |
ps_cn | 策略集组件 | accessRequest,policyContext | policyContext,accessResponse,开启子流程 |
p_cn.tag | 策略组件 | policyContext | policyContext,开启子流程 |
p_fn | 策略循环组件 | policyContext | policyContext |
p_bn | 策略循环中断组件 | policyContext | 无 |
r_cn | 规则组件 | policyContext | 开启子流程 |
ruleTrue | 规则true组件 | policyContext | policyContext |
ruleFalse | 规则false组件 | 暂无 | 暂无 |
addTag.data | 添加标签组件 | 无 | eventContext |
addList.data | 添加名单组件 | accessRequest | db |
sendSms.data | 发送消息组件 | accessRequest | 消息系统 |
setField.data | 设置字段组件 | accessRequest | accessRequest |
cond.data | 通用条件组件 | accessRequest,indicatorContext | 无 |
当然如果LiteFlow
的IDEA
插件能帮我们做这个事情就好了。
小结
先这样了,预告一下,下篇大概率是关于策略模式设计,顺序、最坏、权重、投票,顺便更新一下项目进展请情况。
写在最后
拙作艰辛,字句心血,望诸君垂青,多予支持,不胜感激。
个人博客:无奈何杨(wnhyang)
个人语雀:wnhyang
共享语雀:在线知识共享
Github:wnhyang - Overview
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。