Featured image of post Phoenix框架 从0到1设计业务并发框架 小米商城产品站革新之路

Phoenix框架 从0到1设计业务并发框架 小米商城产品站革新之路

# 前言

小米商城产品站之前由于历史原因,存在着诸多问题与不便,随着技术的快速变革,技术部中台化的建设,越来越不适用于现在快速迭代的业务需求,接下来我将以技术的视角讲解我们遇到的痛点,以及解决这些痛点的思路,也就是 Phoenix 框架诞生的故事。

为啥要进行设计一个框架,其实是业务发展导向的结果,若是我们不进行设计,那么我们会遇到如下一些问题:

  • 在新的产品需求规划下,无法承接大型项目,只能进行小修小改;
  • 小米网产品站最初,每个端一套代码逻辑,风格各异;
  • 历史沉淀,一个接口函数 2000 多行,熟悉代码逻辑的成本越来越大;
  • 隔离性差,服务可用性严重依赖下游,下游一个接口的抖动都会给我们接口带来恐慌;
  • 技术上整体中台化建设,随着调用接口越来越多,接口越来越慢
  • 代码没有解耦,特别对新同事而言,新项目上线风险高
  • 缺少 Go 基础组件的维护,无法对下游接口实时监控

# 思考

我们从技术上计划进行重构,那么我们如何将现有的调度逻辑抽象出一套兼顾稳定性、便捷开发、可维护性且可监控的框架模型是我们首先带来的问题。

我去调研了开源的一些并发框架,发现传统的并发调度模型基本上都有依赖关系、超时控制、线程池分配调度、熔断限流、接口监控等功能。

为啥我们没有直接使用开源并发框架进行开发呢?

我调研发现业界 LiteFlow 框架是最受欢迎与好评的框架,于是在 Github 上面去了解框架底层实现的细节,随着深入阅读源码,发现这款框架设计的是真的很优秀,但是也过于庞大、复杂,特别是 EL 规则的写法,相对来说还是有一定的上手成本。

那么我就在思考,我作为业务开发人员的话,我不想关心这么复杂的依赖关系,只需要关心自己产品站业务调用到的中台的接口及其依赖接口即可。特别是大型接口捆绑了几十个下游接口的逻辑,要是理解每个接口的设计细节更是不太可能的,要是依赖关系特别复杂,那么 EL 规则会写的非常复杂且维护成本极高。

那么该如何设计一款轻量、快速、高效、从根本上解决开发人员手动维护依赖关系的并发框架呢?

既然存在依赖关系,那是不是可以通过算法进行自动构建依赖关系呢?

# 设计

拆分 Task

根据产品站的实际场景,我们发现,调用下游接口若干个,且请求接口存在不同的请求协议与不同的中间件。

单向依赖

更重要的是,接口存在着依赖关系,我们梳理接口调用发现,接口依赖正好是有向依赖图的结构, 那么我们就可以进行遍历依赖关系进行编排并发分组。

并发调用组

这样就解决了依赖的问题,我们可以依次并行执行每个并发组的任务,这样就可以得到所有接口或依赖的结果。

那么获取到结果之后,怎么进行业务逻辑的编排,怎么隔离下游接口,其实原理很简单,既然任务可以进行分层,那么我们业务调用、业务编排、防腐蚀层也可以进行分层设计。

分层设计

  • Transfer 层的作用是业务逻辑层,用来进行业务编排,将 BO 数据提供给客户端使用;
  • Task 任务层是并发执行的核心设计层,在这里通过并发分组的每个子 Task 在这里进行编排后执行调用,用来进行超时控制、耗时统计等操作;
  • Infrastructure 层作为防腐层设计,用来隔离下游接口的调用,这样的设计提高了接口的稳定性;

# 写在最后

好了,上文就是给大家讲解的自动构建并发调用图的业务框架,也就是 Phoenix Framework。

Phoenix

Phoenix,最初在周志明老师的网站"凤凰架构"提及,一方面是对周老师的架构设计理解与 Java 相关知识学习的致敬,另一方面,Phoenix 不死鸟,软件的生命周期也是如此,随着业务的快速发展诞生、并随着业务的的收缩而凋亡,生生不息。

最后,我会以系列的方式进行讲解这个框架遇到的问题以及解决思路,感谢大家的阅读,大家要是感兴趣的话推荐大家关注公众号,让我们一起变得更强~

WeChat