读《蔡学镛-架构思维系列》
2020-01-06 ,2020-01-17,
Reference Link
考虑架构的三个方面
- 技术
- 业务
- 组织
多数情况下,前两个考虑的多,而后一个考虑的少。技术架构出问题,除了技术本身的原因外,通常也反应业务架构规划的不善,以及组织方式的僵化。这些方面都是彼此相关的。
架构的设计顺序是:先业务梳理,再技术设计,后组织梳理。组织架构的梳理是为了业务与技术架构最好地运作。
架构的实施顺序是:先组织调整,再业务重整,后技术重整。
架构的思维是同时包含三个方面的结构:技术、业务和组织,必须考虑到分析、设计和实施的过程,必须估量价值、风险和成本的大小。
建模的重要性
建模(Modeling)和抽象(Abstracting),是架构师(Architect)最核心的能力。
模型(Model)的第一个用途是:沟通的工具。例如,地球仪,建筑图纸。对于软件开发而言,模型就是你对于软件方案的设计,包括系统设计和架构设计。对于企业组织而言,模型就是你对公司的设计,包括组织结构和流程设计。
模型的第二个用途是:有助于设计、实验、观察和改进过程。其实就是通过模型来仿真真实的世界,推演出适合的变化轨迹,并应用到真实的世界上。对于软件开发而言,模型的变化就是对软件的重整(重新工程化)的设计。对于企业而言,模型的变化就是关于企业架构和业务调整的过程的设计。
总之,模型是真实世界的抽象,可以化繁为简,去芜存菁,使得你的思维更加清晰。注意,建模的语言只是一个工具而已,很多人会被建模语言给限制住了,变得很僵化。语言是工具,清楚地表达思考和思想才是运用语言的重点。
建模时,时刻牢记目的是什么,这是成功建模的关键。在建模的开始,模型会被很多没有价值的信息所污染,关键的信息不能浮出表面。良好的建模能力重点是要「去芜存菁」。其关键的两点为:
- 记录和「目的」相关的要点。
- 只记录有差异的点。
例一,如对自己建模,如果是对未来就业做准备,除了学历外,身高、外貌也是要点。如果是对健康做准备建模,学历和外貌这些点就没什么用。
例二,记录差异的点,如果所有人都有,记录的价值就不大,记录本身会导致信息超载(Information Overload)。
抽象是指比较后输出的结果。有两种抽象,一种是同中求异,另一种是异中求同。如果是后一种抽象,那么抽象的结果是概念。如糖、甘蔗可抽象出「甜」;跑步、散步抽象出「运动」。
通常把抽象的结果「概念」和「关键性信息」组合在一起,被称为「类型」(Type)。概念自身的意义是什么,以及类型需要哪些关键的讯息,都要明确的目标才能确认。
建模的方式有两种:
- 一种是使用类型,记录类型所要求的关键性信息,就是和基本概念有差异的部分。
- 一种是不使用类型,会造成概念太广泛。
抽象的过程中会涉及到「分类」(Classification)。先分类再抽象出概念,扩充出类型。分类的目的也是为了更好地抽象,抽象的目的是为了建模。良好地建模的第一个重点是在记录目的相关的要点。持续地抽象会出现分层(Hierachy)的情况。
注意,对「一件」事物做建模,对「一群」事物做抽象。无论是东西、动作、想法或其它,只要目的清楚,任何一群事物都可以抽象为概念,并扩展为类型。
架构的意义
建模的数字化为后期的自动化,智能化做准备。
模型的保存方式与展示方式可以分开。通常可以以MVC方式(Model/View/Controller)来区分资料的模型,展示方式以及操作方式。设计良好的软件系统内部最好能够将MVC三者区分开。
根据使用方式,模型可以分成两种:
- 资料模型
- 程序码模型
资料模型的建模对象是真实世界的事物,且资料模型在执行的过程中会不断进行基本的新增、删除、修改,导致模型持续的变化。
程序码模型的建模对象通常是开发者脑中的想法或算法,程序码可以被执行,且通常会关联到其他的资料模型。正常来说,程式码模型在执行的过程中,不会改变自己的程序码模型,但可能会改变关联资料的模型。
模型是如何产生的,一种是我们自己建立的,如程序码模型。另一种是运作的过程中,长时间逐渐积累建立的,如资料模型。
程序设计是为了功能需求建模。技术架构设计是为非功能需求建模。功能需求是指实现一个购物车,可以记录购买的商品,以后才能提交订单和结账。非功能需求例如,指双 11 期间,支持 1 秒有 10 万人在上线。
业务架构师也需要建模,建立商业模型。业务架构师建模的目的是为了分析业务需求本身。太多的公司在决定做哪些业务时,没有系统地思考,导致资源错误配置,这往往是企业内部许多问题的根因。业务架构师要了解产品、技术、组织结构、资源、用户、市场和竞争对手后,建立一个完整的商业模型(Business Model),再决定要做哪些业务,并且把目标定义在这个商业模型中。根据这个商业模型的规划,根据时间和需求,技术架构师和程序员分别去实现非功能需求和功能需求,同时,组织架构也相应做出调整,避免成为业务和技术的绊脚石。
现代企业的架构流程
一个良好的商业模型(Business Model)描述了一个企业的各个方面的信息,包括内部的因素,包括业务架构、技术架构和组织架构;以及外部的因素,包括用户、对手,市场,法规等,以及这些因子之间的连动关系。通过分析这些因素及其之间的关系,我们就可以比较系统地分析、设计和实现我们的商业目标。
首先,企业要有商业目标,其具体是指三到五年,希望变成什么样子。可以通过分析行业趋势,对标的企业来分析,结合自己的使命和愿景,设计自己的目标商业模型。我们要设计是目的的商业模型,而不仅仅是目标本身。经过几轮的推演,逻辑地分析,找出所有重要的关联因素,搭配市场环境的预期和对用户的理解,为这些变化的因素设定战略目标。
注意,并不光是列出资产收益率、总资产报酬率,负债率的目标指标,要设想有哪些因素会影响这些指标,如员工的人数,研发的支出。同时,也要考量一些难以量化的指标,如管理层的基本素质,中层管理的水准,员工的素质,技术设备的更新水平,产业影响力,产业的经营发展策略,长期发展能力。这些都是目标的商业模型的成分。
在设计目标商业模型时,要先设计业务架构,再设计技术架构,再设计组织架构。一切都是为业务服务的,三者的设计顺序不能变。
接下来,将目标的商业模型所列出来的信息,逐个对比企业当前的状况,记录下当前的商业模型。有了现在和未来的比较,前进的方向就不会错,通常会分阶段实施。实施过程中,必须先调整组织架构,再调整业务架构,再调整技术架构。如果组织架构不能调整,会有大概率失败。
所有规划的实施过程中,现实情况会逐步脱离之前的规划,因为没有人能精准地预测未来,毕竟规划是基于一些假设所设计出来的。所以,要定期地复盘,检讨当前的状况,总结和分享经验教训,修正前期假设带来的误差。通常可以3 个月为一个周期来调整目标。
大的变化会对短期的商业利益带来伤害。如果股东不能支持和理解,管理层难以坚持去做,要说明大股东的支持,也是架构变化得以成功的一个基础。
架构能力的四个阶段
- 架构原则(Principles)
- 架构模式(Patterns)
- 架构建模(Modeling)
- 架构框架(Frameworks)
架构原则,是最基础的架构知识。通常不会有太多条,且每一条比较简单,用处很广泛,彼此独立。
架构模式,是描述具体要解决的问题是什么,具体的设计是什么,会产生什么效果。可以理解为一些经常使用的,已经确定有效的方法,可以直接来套用。
架构建模,是建模所需要的能力和语言。不要把 Model 和 Pattern 搞混淆了。模型是某件事物的化身,模式是方法;模型是一个整体观,模式是零散的常用招式。
架构框架,指模型已经被抽象成为一个更为通用的框架,这个框架可通过简单的配置或小批量的开发就可以产生新的模型。
注意,光是技术架构还不够,如果没有好的业务架构,技术架构就不好做,或是技术架构的价值就体现不出来。
技术架构设计的 12 条原则
在第三阶段,架构建模时可用到这 12 个原则。
- 不要使用 Stored Procedure(存储过程)。因为,如果使用会使得业务逻辑难以维护。像 DBMS 系统的 PL/SQL 等。当前的处理方案是采用分布式。
- 一个系统内部可以包含存储和程序,但系统间不能共用资料。其系统一定是个独立的系统。其可完整地控制自己的数据库,对所有数据库的存取必须通过系统本身,有点像面向对象的设计的封闭。系统间的依赖只能通过其系统开放出来的API,完成系统间的解耦合。
- 逻辑容易变动的程序必须剥离出来成为另一个系统,容易变化的(如应用系统)可以依赖于不易变动的(平台系统)。
- 任何系统都不可依赖于一个易变动的系统。
- 被调用方必须提供清晰、 文档化的 API。
核心系统的 API 应该是 API 数量少,传入参数可以多。
应用系统的 API 应该是 API 数量多,传入参数可以少。 - 用户界面要从系统中可完全剥离出来而独立,界面之间也最好没有相互地依赖。与业务有关的逻辑不要存在于界面上。界面只有用于界面的展示输出逻辑或用于输入的输入逻辑。
- 调用外部厂商的系统必须只依赖于SPI(service provider interface, 服务提供者界面),不依赖具体的系统。API是我们设计并实现介面标准,别人来调用我们。SPI是我们设计,别人来实现。如果我们的SPI与别人的API之间有差异,需要在增加一层adpater。我们的业务逻辑与厂商系统之间有隔离,避免外部系统的各种变化影响我们的业务逻辑。这也有另外,如果你的业务系统变化大,那么,你可以不遵守这个原则。
- 业务逻辑的程序代码必须区分服务service和对象object,服务是没有状态的,对象是有状态的,服务操作对象,对象的状态记录在资料库和外部系统中。模型有两种,一种是资料模型,一种是程序模型。服务归于程序模型,对象归于资料模型,加一部分与资料密切相关的程序模型。同样,如果业务变动多,也可不遵守。
- 服务不能直接读写资料和外部系统。资料和外部系统一定要通过对象的包装与解释,才能被服务操作。同时严格遵守分层不跨层。不太明白。
- 对象的状态保存方式必须做出隔离,提供资料隔离层。对象不需要知道状态保存到了资料库中或外部系统中。
- 充血模型才是好的对象模型,设计时要考虑是否有强一致的要求。不太明白。
- 禁止循环依赖。只要有循环依赖的存在,系统必定糟糕。
这一节写得不太好!
微服务设计的十个步骤
微服务的好处:
- 业务功能点的变化。
- 业务量的变化。
微服务的缺点:
- 设计难度高。
- 运维难度高。
许多企业都号称是使用微服务,但那是假的。主要问题有三个:
- 边界设计错误。
- 微服务的耦合度高。
- 介面的品质低。
十个步骤如下:
- 场景分解:整体环境分�为「用户」、「前端」、「后端」�和「外部」四个域(Domain)。每个层分为操作和资料两个象限。所以,共有四个操作象限,四个资料象限。
- 资料建模:对四个资料象限内资料进行建模,其核心是找出各个象限之间的关系。
- 强一致性的资料聚合:把资料模型做聚合设计,聚合体中的资料必须强一致性。所出现在四个操作象限内的操作各自归类到适合的聚合体内。这一步是微服务设计的关键任务。
- 业务分解(X 轴分解):把前端层分解为 UI 和 APP 两个业务层。把后端层分解为 API(Application Programming Interface),服务,SPI(Service Provider Interface) 三个业务层。
- 技术分解(Y 轴分解):把上面这五个业务层,各自独立分解为业务逻辑层,技术 API 层,技术服务层,技术 SPI 层。
- 处理一致性失败:当微服务之间的资料一致性出现问题时,通常可以先利用「冲正」的方式来处理;如果冲正失败,再人工介入处理。
- 设计消息瀑布:彻底解耦的微服务之间是通过消息来沟通的,消息量大,会影响系统稳定,所以消息不能逆流。
- 设计业务的大数据:对于这些系统产生的业务资料,在设计微服务时,可以同步思考如何运用这些数据,找出其中的业务价值。
- 运维分解(Z 轴分解):把第 5 步中的 象限中的20 个微服务,各自分解为程序、容器平台、作业系统、电脑和网络。
- 设计运维大数据:对于系统在运行过程中产生的技术资料,在设计微服务时,同步思考 如何运用这些数据,找出其中的运维价值。
方法论设计的四个步骤
方法论是指为了达到每个目标的一套做事情的逻辑。有了方法论,其他人就有了可以依循的规矩和流程,降低了事情的难度。本节介绍的是「用来设计方法论的方法论」,即是 Meta-Methodology。
第一步,你必须要有一个参考模型(Reference Model)。请注意,参考模型本身就是模型,并不是 Meta-Model。
以上节的微服务模型为参考模型为例,其是一个通用的技术架构模型。使用了三个维度:业务(business),技术(Tech)和运维(DevOp)。每个维度用分成了数个层次。
一个好的参考模型必须做到:
- 尽可能适用于多个领域;
- 容易用程序代码实现;
- 功能需求容易设计;
- 不会阻碍非功能需求的设计;
- 可以降低继续调整的难度。
参考模型和框架(Framework)有些类似,但是参考模型是虚的设计规范,而框架是实际的程序代码的半成品。有了参考模型,接下来才可能往实现框架的目标推进。
参考模型就像是一个样本(template),里面有许多格子,每个格子的分工及格子之间的通道是提前设计好了的。大家只要根据格子的描述往格子里面填入东西即可。
第二步,要找出填格子的方法。
其关键在于,这个方法要能够配合敏捷开发的流程,可以通过迭代的方式增量式地设计和开发。以往的架构设计方法,没有考虑到敏捷的内容,相对而言显得笨重,当前的商业环境不太可行,没有人能花一年两年来设计一套软件系统。
在微服务的设计步骤中,先是场景为驱动,这符合敏捷以功能点或特征驱动的作法,且场景更全面,更关心用户的目的,也是技术建模与商业建模的衔接点。
第三步,建立自我优化的机制。
在微服务设计中第 8 步和第 10 步,分别对业务和运维执行、分析、调整的机制。
第四步,降低难度。
以微服务为例,一开始,只要求分解前端与后端这两个域,然后继续分解前端与后端为 5 层,接下来再对这 5 层做技术分解,再把分解的结果根据运维来分解。
业务架构团队是公司最核心的团队
注意,是业务架构团队,不是技术架构团队。
尽管在一家公司的业务需求是最重要的,但是对于业务的设计与规划,大家表面上严肃认真地探讨研究业务,其实不有系统性,科学性和协调性。
体现在以下三个方面:
- 各个部门各做各的业务,没有在全公司形成体系,导致资源重复投入的浪费。甚至于,部门之间没有协同,或掣肘。
- 业务需求常是拍脑袋决定的,从竞争对手抄袭来的,没有好好做分析规划,许多需求是「伪需求」,导致做了没效益。
- 需求的优先级搞错了,导致资源错配。因为资源是有机会成本的,做了这个项目,就不能做另外的项目了。
作者觉得需要有一个团队,将业务做一个通盘的规划来避免这个问题。这就是业务架构团队。这不就是高管团队要做的事吗?
另外要设一个岗位:首席业务架构师。其可做到,
-
了解公司 高层的愿景、战略和价值观;
只有战略的理解,才能做出中期的规划(三年);只有对愿景的了解,才能做出长期的规划(五年至十年);只有对价值观的了解,才知道什么可做,什么不可做。另外,业务架构的调整通常需要公司高层的领导的支持。 -
可以和技术架构团队紧密沟通;
如果业务架构不对,技术架构必定一团糟。IT技术变化快,难度高,也容易出错(不稳定)。技术架构最好有适当的抽象来脱离业务进行。同时,对那些技术与业务耦合度高应用架构一定要仔细规划。 -
可以和市场营销团队紧密沟通;
要了解市场,对用户,竞争对手,产品需求的构想,使用场景的深度思考。需要业务架构师建立完整的商业模型。 -
可以和法务团队紧密沟通;
一些行业受国家政策法规影响大,法规的变化可能决定企业的生死,所以要与法务团队合作,对政策法规做出判断。 -
可以对公司的资源进行盘点。
其实就是对公司人才,相关牌照,必须提前准备。
系统重构
系统重构的前兆:
- 一个貌似简单的功能,开发团队需要花长时间才能加入系统;
- 一些促销活动前,技术和运维如临大敌。
系统重构前的评估:
-
是否可以不重构?
全面地评估每一个子系统的目标,功能,介面,关联系统。
有没有其它方案,如升级更好的硬件,或外采他人的成熟系统。 -
开发能力足够吗?
重构开发比单纯开发要难!
开发资源可否到位?长期是否值得?
重构的的步骤:
- 目标选择:团队成员在重构方法的熟悉程度,业务方的支持程度,客户的感受三个方面考虑。
- 规划建模:分析系统现状,对系统建模,设计如何分工完成。具体工作包括,逻辑重构,介面隔离,资料迁移。
- 开发测试:灰度发布,并测试,逐步切换。
- 回顾总结:大家一起讨论,提升个人能力与团队实力。
企业架构变革难以成功的原因
- 领导人的领导力太弱。平稳发展时期,一切都可循规导矩,按部就班进行。领导人能力强不强关系不大。在架构变革之时,动荡大,如果没有一个强力之领导,保守派与改革派相互斗争,越改越糟。
- 领导人脾气太坏。导致优秀的员工处理于离职心态的边缘,大的变革会带来优秀员工的离职,留下的通常是差的。逆向淘汰,越改越糟。
- 企业财大气粗。典型的思维是钱可以解决问题。要人给人,要钱给钱,口气大得很。剧本如下:来一批人,花一笔钱,搞出一堆破事,然后走掉。架构变革的关键在内部,把已有的人做转变,并让不能转变的人不要碍事。
- 领导人是职业经理人。经理人通常由于短期业绩不能做出大的变革。因为大变革一定是长期目标。这样的大动作会伤筋动骨,导致其前途未卜。
- 企业是体制僵化的企业。体制僵化的企业就是人员已经固定的企业。人的事情搞不定,那么架构变革不可能成功。
- 蒸蒸日上的企业,很难进行架构变革。大家觉得活多得干不完,觉得多此一举,吃饱了撑的。最后的结果是变革变成了 PPT 汇报和 WORD 的总结等纸上谈兵的事。
- 平稳期或略为衰退期,企业架构变革也很难。这时 KPI 的压力会比较大,大家会出现内部竞争,部门之间会形成竞争对手的格局和敌我意识,会去拖跑在前面的部门的后腿。此时的架构变革,会是地盘,权力的争夺,以及责任和问题的推委的战场。
难的原因就一个因素:「人」。
技术应用的艰辛探索
Java 的探索之路:
最开始,PDA,机顶盒,家电设备,不行;WEB 应用 applet,勉强;服务器应用,胜利;手机,OS,半导体应用,勉强;Android 手机应用,胜利。
技术应用驱动探索:假设市场有一个需求,根据需求研发一个新技术,后来发现原需求不存在,或市场没有准备好,到处找需求的附著点。
需求驱动:市场已有一个需求,想办法解决,大部分的技术在已有技术中找,小部分自己研发。
如果懂需求的人,自己写代码就好了。实际上,懂需求的人不想写代码。这也许是技术发展太快了。也许是术业有专攻,懂需求的人学不会技术。
在我看来,应该反过来思考这个问题。懂技术的人一定会懂业务,因为业务都用代码实现过了,证明他懂了。
松耦合的关键
系统规模小,复杂度低时,使用单一控制的组织形式即可。
系统规模大,复杂度高刊,使用分散式,松耦合的组织形式。
松耦合(loosely-Coupled)系统是由许多小巧的,自给自足的程式模组组合起来。比如,Linux 的命令的组合,微服务的组合。这些小模块可以随时加入或从系统中移除,而不影响系统的整体性运作。
此处设计的关键�是「讯息的传送」。
当一个模组收到一个讯息,经过处理,产生了另外一个或多个信息。这其实有点像维纳的控制论的讲法。消息中间件可以完成这个功能,但是也要注意,消息可能会引起消息风暴,比如交换机的广播风暴,有一个机制来预防消息风暴。
消息流最好是瀑布流,没有 Loop 在里面。上下游关系要十分的明确。基本的步骤是:
- 先把所有的消息类型排列出来;
- 设计多个消息中间件,每一个只经手某些类型的消息;
- 消息必须明确上下游。每个模型根据各自关联的消息,连接到某一中间件。
高速大量业务的应用架构关键
设计关键应用时,如期货交易系统,关键在于,想要高速,就要减少 IO,想要大量,就要有缓冲空间(buffer)来做批处理。
高速:可减少硬盘的 IO,在内存中完成业务。但是,内存断电会丢资料,所以,要快速写入硬盘一些资料。关系型数据库的优化,大部分主要是取,而不是存,不太适合写入。一个合理的方案是 event souring 的资料储存方式。
大量:使用 Buffer。
应用架构为:
内存计算+微服务+Event Sourcing+请求buffer+当机支持。
�