LiteFlow上下文与组件设计,数据依赖梳理

个人博客:无奈何杨(wnhyang)

个人语雀:wnhyang

共享语雀:在线知识共享

Github:wnhyang - Overview


参考

如何理解上下文这个概念? | LiteFlow

🌯数据上下文的定义和使用 | LiteFlow

我的业务项目是否适合用LiteFlow?

在选择使用LiteFlow之前应该要对其有一些了解,不求熟悉源码,但对于其设计思想还是了解一下的。这将对于后面使用有很大帮助,官方文档和源码都是很好的学习路径哦!

如官网所讲的,为了实现编排,就要消除组件的差异,由此设计了上下文。而使用LiteFlow完成业务,上下文与组件的设计又是极其的关键。方法论还是交给会写论文的人来吧,我只能提供一些经验之谈。

下面还是通过项目https://github.com/wnhyang/coolGuard/来讲述吧。

image

明确数据流转

无论做什么都要对业务足够熟悉,尤其是在使用LiteFlow时更要对数据流转有把控。

官方讲:其实,使用LiteFlow并不一定要承载你的所有的业务。由于LiteFlow的执行是由执行器对象发起,所以它可以承载你业务中间的任何一小段。

所以LiteFlow可以承接所有业务中间的任何一小段。而至于选择哪一段是使用者决定的,当然我们在选择使用LiteFlow时当然也是看中了其灵活编排、热刷新等特点,应该也是有些想法的了。

那下面就从LiteFlow执行器执行开始吧!对应上图服务选择这一步。

初始化上下文

这时还在execute之外,这一步初始化所有上下文数据,当然使用重载的传入class的方法也行,初始化参数传入也是可以。

image

输入处理

到此大致执行了:THEN(a_icn)a_icn表示输入处理组件,用于一些预处理、简单的加工和输入日志打印类工作。

如下,在使用LiteFow执行器执行时将后面需要使用的上下文作为参数丢给执行器。在下面开始之前需要额外说明一下,虽然上图的整个流程看起来是一部分,但是在实际运行时其实拆分为多个子流程执行的。这一步执行器传入的chainId是个变量,这也意味着从这里开始就具备可编排的可能了。决策与非决策、批量与非批量、同步与异步、字段解析与不解析,等等。

image

对于此步骤能想到的是node(系统字段)、node(动态字段)、node(流控降级组件)等之类吧,目标是做ETL和流量治理一块的,还没想好,所以先搁置一下了。😂😂

普通字段与动态字段

到此大致执行了:THEN(a_in,nf_cn,df_cn),项目为了灵活性的数据接入接受参数的为Map<String,Object>,风险一定会存在,这个应该放在前面的校验上,这里重点讨论的是将输入参数转为系统可识别的系统字段,nf_cn表示普通字段处理组件,做的事情包括:根据配置将输入参数转为可识别的系统字段,设计的内置字段的解析(身份中、手机号、ip、经纬度等归属地运营商等),这个解析也预留了接口保留其扩展性,后面可以在讲;df_cn表示动态字段处理组件,普通字段是直接由输入参数转换而来,最多做一下类型判断、小数位数保留等,而动态字段是由普通字段衍生而来,是通过编辑脚本实现的,使用场景很丰富,最简单如取身份证前6位,交易金额是否是5的倍数,都可以。

nf_cndf_cn都只操作accessRequest输入上下文,解析后的数据也统一设置在accessRequest里。

image

指标计算

到此大致执行了: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指标上下文中。

image

策略集/策略/规则

策略集

到此大致执行了: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响应上下文中。

image

策略

到此还是在:THEN(a_in,nf_cn,df_cn,I_F,ps_cn),但执行的是策略集的编排ELLiteFlow的编排特性在这里会有体现,举个例子:一个策略集下有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表示策略停止组件,用于顺序执行规则时满足某些条件停止后续规则执行。这个过程中拿accessRequestpolicyContext,计算完策略的结果后放policyContext,最终会有上层策略集将所欲结果按编排放入accessResponseEventContext,就是栈的模式嘛。

image

规则

到此也还是在: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则并行执行ruleTrueaddTagaddListsendSmssetFiledruleTrue表示规则结果用于最终决策,除此之外都是可选项,addTag表示增加tagaddList表示添加名单,sendSms表示发送消息,setFiled表示设置字段。这些组件其实应该有更广的应用场景,但目前统一放在规则里,后续可能让其更具灵活性。这个步骤拿accessRequestpolicyContext,放policyContextaccessResponseEventContext

image

输出处理

到此执行最后一个a_ocn输出处理组件后所有流程就都结束了,此过程主要是放accessResponse

image

回顾组件和上下文

以上所有仅代表个人目前的一些用法,仅供参考。

在使用LiteFlow进行规则编排设计时,要明确抽象出组件数据来源和操作数据上下文。数据来源针对的是对execute执行后依赖的规则上下文或参数里的数据,自己的tagdata或者其他的组件自有数据(不管是声明式或非声明式使用的其他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

当然如果LiteFlowIDEA插件能帮我们做这个事情就好了。

小结

先这样了,预告一下,下篇大概率是关于策略模式设计,顺序、最坏、权重、投票,顺便更新一下项目进展请情况。

写在最后

拙作艰辛,字句心血,望诸君垂青,多予支持,不胜感激。


个人博客:无奈何杨(wnhyang)

个人语雀:wnhyang

共享语雀:在线知识共享

Github:wnhyang - Overview