背景
在复杂的业务运营系统中,比如视频的排播系统,会依赖多字段组合来决定业务逻辑,如果有准确的字段级血缘关系,提前知道字段变更影响范围,辅助运营操作业务系统,将会有效降低线上运营事故。
前面两篇文章,我们分别探讨了通过AST抽象语法树、trace链路跟踪获取字段级血缘关系的可行性,两种方法都存在一定的局限性,并不能得到一份准确而全部的血缘图谱。
统一计算框架
前面的场景是基于总线-订阅模式的讨论,如下图所示
要想输出稳定且准确的服务内字段血缘,建立协议规范,从源头控制是一种很好的方式。这里整体设计如下:
从总线-订阅模式改成统一计算框架模式,规范计算逻辑,收拢订阅和写入字段范围和权限。以下展开说明两阶段血缘采集的步骤:
- 一阶段采集静态血缘
分为几部分:
- 计算逻辑编码
在同一个的代码仓库中编写字段运算逻辑,定义一个通用计算函数代码,比如字段a的写入函数,如文件fieldA.go,内部为一个计算函数 func calField(subFilelds []string) {xxx} ,定义出依赖字段和目标字段,数据注入和权限由计算框架负责,函数内部仅关心计算逻辑,这里可制定代码规范,单元测试覆盖率要求,保证代码质量; - 代码合入主干
此时触发CI/CD流程,进行代码自动化检测; - CI/CD
CI会自动化进行静态扫描、单元测试覆盖率检查、代码规范检查,合并成功后自动进行CD,同时提取函数内的依赖字段和目标字段上报至数据血缘解析模块,生成静态数据血缘,该血缘关系的更新需要等下次代码的更改才能更新,同时推送计算函数至数据计算模块; - 数据血缘解析
收集第一阶段上报的原始数据血缘关系,解析及转化成适合图数据库的结构化数据,并存至图数据库,方便后续检索;
至此通过第一阶段上报的依赖字段和目标字段,可形成静态基础血缘关系,将所有写入字段的计算逻辑统一管理后,该阶段形成的数据血缘覆盖率能达到100%
- 二阶段精细化
第一阶段生成的数据血缘关系为静态数据,具有较高的覆盖度,若字段计算逻辑不更新血缘关系就不会更新;定义的依赖字段很可能在实际运算并没有参与计算,即引入了无效的依赖字段,会导致数据血缘关系下降,因此需要动态收集实际参与计算的依赖字段,提升数据血缘的准确性,从而需要第二阶段的数据血缘上报。
● 数据实时变更流水:监听业务数据变更流水,用于触发数据计算模块的字段间的逻辑运算;
● 数据计算:该步骤为业务系统中的核心环节,每接收到当前计算函数相关字段的变更流水,触发一次运算,从而可以计算出目标字段最新的值;
● trace上报:该步骤收集计算函数实际运行时的状况,将实际参与计算的依赖字段才进行上报,进一步精确化血缘关系。
经过一阶段静态采集和二阶段trace链路染色剪枝,数据处理完,我们就可以得到一个准确的字段血缘图:
总结
上面应用场景是把分散在各微服务的计算逻辑统一到一处,通过一个微服务go解析器模式来触发和运行各计算函数,完成数据注入和最终写入。
对于单一的微服务来说,可能存在单字段计算量过大影响其它字段计算的问题,后续进一步迭代,我们可以将函数计算部分通过FaaS来替代,提升服务使用率和系统稳定性,同时可以将需要单个计算逻辑编排成一个pipeline,实现更复杂的业务逻辑。