京东到家业务网关介绍
目 录
-
前言
-
业务网关介绍
-
业务网关面临的主要挑战
-
业务网关解决方案
-
总结与展望
前言
业务网关介绍
如图所示,京东到家首页f eeds流展示了商品基本信息、价格信息、促销信息、门店信息、运费信息、红包及优惠券信息、轮播资源位、限时抢购、活动引导图、榜单入口图等多类元素, 每一个元素 都可能 来自不同 领域 的 基础 服务,如商品系统、价格系统、库存系统、促销系统 、 CMS、优惠券系统、门店系统、推荐系统 等。
feeds流 网关要聚合完成这个页面的所有展示元素 首先要把这些资源的数据来源和上游基础服务以及基础服务依赖关系关联起来,如给用户呈现的商品skuId来自于推荐系统,商品展示的图片、名称、规格等信息来自于商品系统,商品的价格和促销标分别来自价格系统和促销系统,一些活动资源位如轮播图、宫格等又来自CMS。 由于京东到家是基于 LBS的 本地即时零售平 台,所以首先要通过定位系统获取有效的服务门店列表,然后通过这些门店作为入参来获取要展示的内容。简易示意图如下:
• 编码风格不统一
不同开发人员有着不同的编码风格,就连开发过程中用到的线程池都有很多种使用方式,这样会导致系统交接时新接手人员要掌握不同编码风格,同时又融入了自己的编码风格,经过多年迭代之后系统越来越难维护。
• 系统臃肿
业务网关是直接和用户交互的,相较于底层基础服务,它在业务上的 “玩法”更加多变,需求改动也更加频繁,一些功能逻辑要兼容多个App版本甚至要兼容不同的端(IOS、Android、H5、小程序等),在长时间的功能迭代后不可避免的导致一些兼容逻辑散落在各个地方,从而让系统变得臃肿,维护和迭代起来会比较麻烦,甚至存在一些潜在的风险。
• 重复造轮子
下图页面为京东到家附近门店列表资源,每个门店资源展示的元素都来自门店基础服务、购物车系统、评价系统、月售系统、时效系统、距离服务系统、运费系统、红包系统、优惠券系统、促销系统等多个基础服务聚合,而展示门店列表的页面又很多,如一些促销页面,活动页等,假如有需求需要新增一个门店标就需要涉及展示门店列表的网关都要聚合进去。
• 聚合 效率非最优
由于业务网关需要调很多基础服务或中台服务的接口,本身又直接面向 C端用户,作为流量入口,接口的调用量非常高,开发人员一旦不注意对上游接口的调用效率,比如接口能调用一次的调用了多次,能批量调用的结果单次调用导致对上游接口的压力过大,或者基础服务接口调用的依赖顺序没做好,该并行调用的接口串行调用了,又或者线程池使用不当等,都会损失系统吞吐量,如果只靠横向扩展机器,显然是从业务网关到上游服务都是要投入更多服务器成本的。
了解了业务网关的一些痛点后,才能针对性的给出解决方案。我们先将业务网关的聚合工作转化成业务模型。
通过简化 后的 业务模型, 我们看到底层基础服务 通过一组规则按流程进行执行,像极了我们常见的一些工作流或者流程编排一样的东西 , 那是否能从流程编排的思想里解决上述痛点呢?
关于编排 的概念 有很多,如 工作流, 服务编排、容器编排、任务编排等,其核心逻辑都是将一些需要执行的逻辑通过一些规则定义出先后依赖执行顺序,只不过面向的业务场景不同。 在流程编排方式上也有多种思想,这里简单介绍两种以及优缺点对比。
• Pipeline模式
这种模式是将一个个需要执行的任务抽象一个个步骤,一组步骤抽象成一个执行阶段,多个执行阶段根据先后依赖顺序组成一个执行管道 Pipeline,这种方式在处理复杂业务流程组合的时候比较容易想到,在遇到一些复杂业务逻辑时也能清晰的表达出来,便于维护和扩展。
但是这种模式也有些缺点,解决不了组合时间最优的问题模型,下图是我把这类问题简化成一个简单的流程组合,实际业务场景可能要比这些复杂更多。
第一张图要执行一个这样的业务流程,我们如果采用Pipeline模式会发现Task 3 要么和Task 1 并行执行,要么和Task 2 并行执行,总之执行时间为 300 ms,需要把Task 1 和Task 2 先串行封装成一个任务再与Task 3 并行才能减少执行时间。很明显,这样会产生一些问题,比如破坏了任务的独立封装,并且还需要开发者去具体关注这样的场景,在一些负责业务开发场景中,可能还不知道具体要执行的时间,所以让使用者保证执行时间最优是不太好的。
• 任意组合模式
这种模式解决了 Pipeline模式 的缺点 , 同时也拥有 Pipeline模式的诸多优点,只关注任务本身执行的先后依赖,不会等待无关的依赖顺序,使用者只需要按依赖顺序配置好续执行任务即可,把更多的精力放到处理具体任务的业务中,所以京东到家的服务编排工具选择了这种模式。
京东到家服务编排工具由三部分组成: 执行单元、流程 控制器和数据池, 其中执行单元用来定义任务执行所需要的执行条件,如任务执行的超时时间、线程池、执行状态、后续任务等,流程控制 器用来按编排流程去执行和控制任务的依赖、聚合、超时、异常等,数据池则是将 任务执行后的结果数据放入到全局可见的数据池中,调用链路生命周期可以共享。
通过实践发现,业务网关的执行逻辑引入流程编排框架后,虽然也额外增加使用门槛,但优势也更加明显:
• 开发规约
流程编排 “约束”了编码方式,让开发者将注意力集中在业务线的设计和实现点的编码,按照“一切业务皆可编排”原则,所有的业务先按照相对固定的思维去设计“线”,再扣“点”,当开发者结合产品需求对“线”的设计完备以后,完全可以沉浸于“点”的实现,并且可以按照“点”的特性安排不同的开发人员进行完成,不仅“强制”统一了开发规范,而且还提升了开发效率 , 也更适合团队合作开发 。
• 业务功能 内聚
业务逻辑长时间迭代导致代码层面臃肿的问题,我们 通过 使用 流程编排 框架 , 将 不同的能力被分组聚合 成一个个服务 ,各个 服务的 能力职责单一,只需要按一定的规则进行业务流程编排即可 , 这些服务不做任何展示层逻辑或者数据结构封装,只做数据的 RPC查询 , 整体就像搭积木一样。但是实际存在的各个版本、甚至各个端的兼容逻辑依然存在,这里引入了防腐适配层概念,将这些代码逻辑尽可能不影响展示层数据封装结构和流程编排数据获取,最大限度保证业务的灵活性。
• 业务组件复用
通过分析业务网关 聚合的展示资源, 其实业务网关所要聚合组装的内容无非是销售资源(商品) 、 促销资源(优惠券) 、 门店资源 以及一些引导资源(活动图、banner资源位)等,我们将这些组件或者功能流程沉淀下来,封装成统一的资源组件 或者通过服务编排组合成一些公共效率中台服务 ,这样就会被编排进更多的业务规则中,在各个 领域的业务网关 中复用 。
• “俯视”整个业务流程图
随着业务的不断迭代和功能的不断增多,再加上开发人员相互交接,要贯通所有的需求场景对任何人来说都不是一件容易的事情,对业务的理解和维护成本越来越高,通过使用编排规则,我们可以不用大费周章的梳理业务流程即可俯视整个业务的功能重点,及各个 展示层页面 维度的数据来源,大大降低系统交接带来的风险和理解成本。流程编排的职责不仅仅是 “定义规则”和“管控规则”,更在于对 业务 规则的描述。
• 缩短开发周期
流程编排提倡能力复用,通过编排大部分已经实现的能力和少量新编码的能力来完成业务流程,并不断沉淀新能力以面对更多需求迭代。这是一个不断进化和自我成长的过程,通过这种能力的不断沉淀和增加,使得我们在新增一个页面的时候,只需要将原有的已经大部分实现的流程进行规则编排,只需要特殊处理些展示层逻辑即可,可大大缩短项目开发周期 , 因为 从零到一的过程是站在已有能力的基础上进行快速迭代的。
在业务快速迭代的背景下,如果 系统的 基础架构设计不好,在未来随着业务的不断增加,系统也将变得越来越难维护,甚至存在潜在风险。要想使系统 保持灵活和易用 , 就需要 不断的寻找使系统变好的驱动力,而这种驱动力正是不断的挖掘系统潜在的风险和痛点才能获得。另外也要不断向行业内领先的 解决方案 看齐,了解自己系统 存在 的差异, 才能不断进步和完善。