2018 November 01 —— improvement

平台化的阅读记录与思考

SaaS 服务平台化的一些思考

行业的脉动与技术发展的气势

在一家业务膨胀与上升态势的公司感受技术的价值,业务推动技术改造,技术支撑业务的扩张,技术所面临的压力,技术的变迁过程,这些都是很难有机会能够触碰的.

技术无时无刻不面临着压力,技术不停的需要改造与迭代用以支撑业务,让技术知道自己做的是有用的技术.

技术的价值何在?技术的价值靠什么来体现?技术陷在自己的圈子里面自嗨,但却无法满足业务的需求?

服务的平台化与业务的多样性问题;

美好的愿景: 基于一种平台做通用化的上层开发.工业化时代的思想,流水线通用化作业,节约成本.

如果各自分散研发将导致成本陡增,单词研发成果被生产线复用率越高,该研发成本被均摊到结果上最终则越低. 如: 瑞典 CV90履带式装甲战车,通用化的履带式装甲底盘,基于该底盘衍生出了诸多形态的战车.而驱动这种通用化设计的则是成本以及效率.

基于通用化底盘构造个性化上层.

如: F35系列, 同一机体平台且绝大多数零部件通用, 通过特定化的配置实现海军版/陆军版/空军版,构建不同的产品特色;

考研设计师的智慧与管理能力.通过平台复用节约成本在工程领域同样适用.

关键字: 成本 效率

软件开发时代的变迁

1.0: 耦合的系统,无模块业务边界,无法独立化.

2.0: 1.0系统演进过程应用日渐臃肿,内部模块在其他新建垂直应用难以复用. 新的应用对应的基础服务都需要重新搭建,重复性建设工作多. 利用分布式以及SOA思想来改进构建2.0系统.

SOA 架构: 互相耦合的系统功能抽取出来,拆分成独立小系统,这些小系统的复用可以一定程度上避免重复建设.

中间件: 相对独立而又基础的系统抽离出来构建为中间件.

矛盾的演进

随着业务需求与环境的变化,矛盾也在演进,原来不是主要矛盾的矛盾经过逐渐发展成为了主要矛盾: 一段时间有一段时间的目标,针对目标理清楚当前阶段的主要矛盾与问题是什么.

复杂的业务如果不停的利用if/else 解决问题,最终没有人能够完整的知道系统的具体能力,有哪些功能,所有的逻辑都被沉淀在 if/else 中. 而业务的交接与人员的变动则让原本脆弱的 if/esle 不堪一击,迅速被业务的变动击垮.

源码面前,了无秘密 — 在超长的 if/else 面前,一切源码在有限的业务了解时间内失去了原本的意义.

重新构建? 抛弃历史包袱? 系统的问题,与系统之间的牵连,系统中积累的丰富业务逻辑与规则都是制衡因素.

重构?

系统的重新抽象?

因为随着业务的不断发展,原先定义的域已经被极大的泛化和扩展,解决这些域的问题又分别要用到哪些能力,而这些能力,哪些能够进行扩展,哪些不能扩展, 如何进行扩展,另外一个问题是,不同的业务,该以什么样的流程组织这些能力以及进行扩展,而系统又该如何理解这些能力。

不同业务可能对系统中的不同能力进行扩展,一旦扩展信息使用了 if/else,就陷入了原有的死胡同.

引入统一元数据管理中心来进行扩展管理,定义各个系统域的能力, 域通过域服务来暴露自己的能力,并引入域之间的服务调用与流程的扩展管理.

业务流程的抽象分析?

开闭原则

要保持扩展的可持续性,开闭原则非常非常重要。「对扩展开放,对修改封闭」,这句话说起来容易,但真真正正做到则非常非常的困难。总会有各种各样的原因来诱导你打破最初系统架构设计之初所设计的约束规范,如何合理的做出抉择,并且让这些变更符合开闭原则,考验着每一个架构师的智慧。

架构的理念要想得到诠释与执行,需要让代码按照统一的架构风格有序编排,需要从架构层面保证所订立的约束被完整执行.

带着枷锁跳舞

业务与业务之间,业务与平台之间的部署隔离.如果基础与上层无法隔离,就会对后期的维护造成巨大影响,细微的变更需要大量的回归.

尺度效应: 所谓的“尺度效应”是指当尺寸放大之后,构件的承力面积与线性尺寸成平方增加,而构件的重量却随尺寸成立方放大,因此,尺寸加大到一定程度,结构中的应力将急剧随尺寸加大而提高

元数据: 描述数据的数据;如: 用身高/年龄 等信息描述人的信息,用照片的 exif 信息描述数码照片信息.

总结与思考:

  • 平台化与业务多样性: 变中抽象不变,建立系统模型,约束开发规范保持系统模型符合架构设计,架构不被业务侵蚀而变形.通过配置不变来支撑业务的变化.

  • 服务的平台化,与开发的效率化,业务迁移的代码复用度.

  • 互联网的快速变化,一步慢步步慢,没有过多时间来各自独立开发, 一旦停下来商业模式可能变化,进一步导致业务变化,从而导致最初的停下来想做的事最终可能没有解决当前的主要矛盾(矛盾变化了,做了一半的事情却不能半途而废).
  • 技术对于业务的快速响应能力.体现技术的价值所在,这个能力非常考验架构师的设计哲学
  • 通用化/平台化的原始诉求来源于业务的推进改造
  • 从最初构建的内部耦合严重的单应用系统,经过拆分/解耦,内部子模块的重构/沉淀/合并/拆分,解耦成为一个个独立的子系统.
  • 业务在发展,商业环境在变化,问题也在变化,矛盾与问题都在同步演进
  • 复杂业务中被 if/else 束缚的业务扩展能力与维护能力
  • 找到业务数据的元数据,利用元数据来定义业务数据的抽象.针对业务流程进行细化与拆分,整体的流程可划分为多子域,找到子域的元数据描述,利用元数据管理中心来管理业务能力的扩展(这里有点模糊,有些意识但又没有Get 到点),以及利用域的服务来暴露服务能力.

旁白: 这里回忆之前看过的 DDD, 领域编程模型,结合起来看.

  • 开闭原则.守住原始的系统架构不被破坏.如何根据业务做合理的调整,如何约束变化与扩展,保护系统的架构理念不被错误执行与错误的理解?
  • 系统之间的隔离非常重要,否则给测试的压力非常大,每一次业务的修改都牵一发而动全身.

  • 尺度效应. 巨无霸工程的维护难题?
  • 重构的过程新业务的同步开发,给高速运行的飞机更换发动机…. 新老的过渡阶段如何逐步过渡?
  • 平台化与业务多样性的矛盾会一直存在,只能平衡而无法根治,带着枷锁舞蹈.
从 Eclipse 平台化学习

平台化: 可复用性/ 可配置性

adpater 的核心意义: 开闭原则, 对外扩展开放, 对内修改关闭.

开放扩展如何不改动核心类, 如果在内部无感知的情况下扩展新特性?

新特性的更改如果建立在直接对内部核心类的操作与扩展上,这对于系统的影响是巨大的.新引入功能和已有功能实现隔离,在各自的实现类中完成各自独立的逻辑实现.

保持核心类的稳定,意义重大.核心类的修改影响系统稳定性,核心类随业务修改会导致类库的迅速膨胀.

考虑扩展性,新 Feature 的特性?

交易平台可以说是目前阿里中设计业务方最多的平台,B2B,航旅,O2O,虚拟商品,生活服务等新的业务快速增加,对业务的支持能力是交易平台化最核心和头痛的问题。

业务方多且杂,如何承接各业务方需求?在保持核心类库稳定的情况下,迭代新的 Feature 就显得尤为重要.开闭原则的核心在此体现.

Quote:

大型软件架构的平台化 VS 业务多样性,如何取舍?

淘宝商品详情平台化思考与实践

平台化三部曲之一微核心可扩展架构 - 从Eclipse平台看交易平台化

平台化三部曲之二模块化开发 - Google Guice 平台模块化开发的果汁

平台化三部曲之三流程编排 - 平台化是舞台,流程编排就是导演一场戏

元数据(MetaData)

Guice DI 看平台化

从系统中剥离对象的直接构建, 将对象的直接依赖改为引用接口的依赖,同时将对象利用工厂的形式构建.(Factory 模式的使用),利用注入的形式将对象注入.

工厂的对象构建通常是重复代码,可以做到配置文件定义化或者是注解描述配置.

利用框架来作为超级工厂,也就是构建对象的工厂的工厂,利用配置文件来配置构建工厂.

DI 对单测的好处,可以 Mock 接口注入依赖对象更简便的实现可独立测试.

Spring 利用 xml 配置.

Guice/ Dagger 利用注解配置.

注入- 接口与实现 bind, 通过对应的接口与实现的 bind 指定对象构建的实际对象.

Guice 构造对象的形式:

显示注入: 指定配置模块, 配置参数相关.

隐式注入: 构建依赖树, 依赖项的依赖项.至到根配置,只需要最核心的配置就可以完成整个注入配置,在合适的地方插入根配置.

依赖注入对象的作用域. 全局作用域/自定义作用域(随宿主对象)/无配置作用域

由于比较了解 Dagger 可以看出 Dagger 其实和 Guice 非常相像.

https://www.ibm.com/developerworks/cn/java/j-guice.html

平台化舞台

业务系统的角色, 角色的扮演, 角色的划分, 角色的职责. 导演指定谁扮演什么角色?

软件的开发者与架构者指定角色.

产品经理负责编剧指定想要的业务需求与场景, 导演借助平台化工具迅速构建对应的场景流程响应编剧设计.

高效率: 流水化作业, 分工明确, 职责清晰.

业务系统开发围绕业务本身快速构建,流水化作业生产

调用各角色,组织资源协调
按需而变,分解复杂剧情,调配各资源.

复杂的问题会在任何领域都出现,但是解决它们的总体策略通常是一样的:分而治之。我们会将问题拆分为更容易解决的子问题。然后这些方案再按照与分解相反的方式组合在一起形成整体的解决方案。 通过观察会发现这样的问题是经常发生的;借助于经验,能够识别出最优的方案。我所讨论的就是模式,这些模式被命名为企业集成模式 (Enterprise Integration patterns), 由 Gregor Hohpe 和 Bobby Woolf 进行了分类和总结,他对我们进行复杂业务的解决方案提供里整套的总结,为我们对复杂业务处理流程进行最优化实践指导。

为解决复杂业务开发提供了整套解决方案 — SaaS.

EIP , 松耦合, 数据作为消息传递. EAI 模式中模块之间具有相同的接口. 类似 Linux 中的 pipe.

模式之间的组合通过接受一个模式的输出作为另一个模式的输入. 模块之间通过相同的接口进行数据传递.

基于通用消息时间进行中间传递中转.类似于 Android Binder 机制.

EIP 核心概念:

  • 消息系统
  • 消息通道 : 模块间消息传递的通道/ 事件总线
  • 消息过滤器
  • 消息路由 : 解耦独立的消息处理步骤,以便消息能够在某些特定的条件下被正确传递到对应的过滤器中处理.
  • 消息转换器: 不同的数据结构模型
  • 消息端点

针对复杂业务问题可以分治简化,最终成为子模式与子模式之间的组合问题.

将复杂问题简化为满足需求的模式组合.对复杂性进行隔离与组合.

平台的核心:

  • 简化外部系统的连接调用方式, 消除不同系统之间调用的差异,系统的调用细节由平台完成,复杂逻辑在平台内部处理,对调用者透明化,平台提供一致性调用模式.

  • 对流程的描述提供 DSL 语言支持,简化流程设计.

  • 流程进行运行时监控与生命周期管理.

  • 完善的错误报警机制

重点:

屏蔽外部调用之间的差异,子系统可以异构,但平台通过定义的约束抹平子系统差异,进而通过平台提供统一的集成模型.

平台提供抽象的一致的访问形式,消除系统之间的差异,平台对集成的系统提供了更加简单的访问形式.

如: 利用 URI 寻址访问: systemA://service?type=value.

服务调用的标准一旦确定

DSL 本身有些接近于伪码,DSL 描述可以更加贴近业务,剥离无关语言层面的细节,更加抽象,更加高效.

https://yq.aliyun.com/articles/772?spm=a2c4e.11153940.blogcont39.20.54f8570fMGwxSt

OSGI

OSGI 定义了标准的组件系统, Eclipse 就是基于 OSGI 框架的应用.

OSGI 框架定义了组件规范, 组件 Bundle 由提供 Bundle 自身功能资源的 MANIFEST.MF 文件与其他资源构成.

Bundle 的解析: Bundle 中的所有包约束条件满足才可被正确解析.

Bundle 解析成功后由 OSGI 框架针对 Bundle 构建独立的 ClassLoader.

https://www.ibm.com/developerworks/cn/java/j-lo-osgi/index.html

https://www.baeldung.com/osgi


平台化代码实践

平台化的核心:多端代码复用

多端:

  • 相同业务的多入口

外卖业务统一标准化服务平台, 基础能力标准化,推进多端复用,输出技术服务平台.

多端问题:

  • 一个业务多端入口

外卖入口: 美团外卖 App / 美团 App 外卖频道 / 大众点评外卖频道

由于底层生态不一致, 上层业务各自独立开发,一个需求多团队分别独立实现.

目标: 一次开发,多端少量适配.

  • 平台中其他业务的基础依赖- 外卖平台中的基础功能被其他兄弟业务依赖.需要提供基础功能的多端复用.

基础功能的标准化复用.

复用的核心之一: 组件化

代码利用不停的 podconfig 打出不同的渠道包, podspec 区分.

基础

底层依赖一致性, 底层融合才能一致性的构建上层业务.若底层存在较大差异则建议重构融合底层技术栈.

技术栈统一的必要性非常重要 启示: 全渠道组与架构组的输出需要有一致性,保持统一,防止整个 SaaS 端被分割.

底层的差异应该被基础服务封装,不被上层业务感知.否则上层业务的实现会有诸多赃代码. 利用接口定义底层服务,屏蔽差异化,接口实现保证上层可调用的服务完全一致.

实现方案

满足现有为主,实现未来最佳规划为辅.

不要求一步到位,完全解决历史问题, 但应该有一个逐步解决的过程.

Android 平台化的逐步迭代
  • 初步方案: Delegate 实现, 管理差异,各自实现

问题: Delegate 差异接口集合会随着业务扩展无限扩大,且对于内部业务的侵入性很强,很多内部模块会调用到 Delegate.

  • 进一步总结: 差异化管理/基础组件,服务的复用

利用 sourceSet 配合 flavor 构建特定包.

  • 组件化,提高复用率

  • 页面复用,页面组件化,利用七巧板式构建.

美团外卖iOS多端复用的推动、支撑与思考

美团外卖Android平台化架构演进实践

平台化架构实践:

目标:

  • 代码复用
  • 平台化 : 从单工程开发进化到平台化协同开发.
代码的 fork 实践

底层的差异会导致上层各自独立演化,最后导致体系各异.

sdk 拆分重用的实践

通过和产品、设计同学的沟通,约定了未来的需求,会从需求内容、交互、样式上,两端尽可能的保持一致。经过多次讨论后,团队发起了两端代码复用的技术方案尝试,我们决定将搜索模块从主工程拆分出来,并实现两端代码复用。

底层差异如果过大,上层强行合并,即使基于接口进行构建,但当大量接口实现散布在主工程之后,在多渠道业务并行开发之后,会导致代码无法回流统一.

页面组件化

页面细化,拆分,可解决页面巨大化,但无法解决组件化之后的代码复用问题,组件化之后的上层业务无法寄生于差异过大的底层体系.

底层差异过大也导致页面的组件化拆分无法进一步进行.

优雅的设计模式

CleanMVP

优雅的设计模式可以一定程度上解决问题.

通过定义复用与可变层, 在可变层引入 Convertor , 不变层

结论: 多端代码的复用,底层统一是必然

中间层的设计可以解决多端代码复用的问题, 但是如果底层服务本身扩展性足够强,中间层的引入反而会让原有框架丧失扩展性. 如针对Retrofit 的二次封装.

  • 基础 SDK 层,与平台层的架构,基于平台构筑上层业务.

美团外卖Android平台化架构演进实践

美团外卖Android平台化的复用实践

大型软件架构的平台化 VS 业务多样性,如何取舍

上一篇
下一篇
Loading Disqus comments...
Table of Contents