摘要

软件行业作为一个高速发展的行业,从诞生的时候为了通过解决遇到的重复或者规模化的运算问题开始,随着科技进步以及IT基础设施的演进,软件行业也不断的壮大发展。从最早的支撑非常少的高精尖领域的科研领域,行业人士认为全球只要5台计算机就够了,而进入个人PC时代,比尔·盖茨也说了著名的“640K内存对每个人都足够了",而到了现在,人类生活中无处不在的软件,随手触摸到的计算机设备的性能已经远超当年支持全球的5台计算机,一个小设备的内存也不止640K。

从这个趋势来看,软件架构的趋势也是随着基础设施的规模而不停的演进,软件从最初的非常简单的单体软件架构匹配以大型机的计算要求,到PC时代所谓的CS架构、互联网时代的BS架构以及当前针对云计算架构所演进出来的各种架构趋势:容器化、微服务及组件化、低代码等,而伴随着物联网的需求越来越真实存在,云端协同的架构设计、通讯模型等也都一一涌现出来。

软件架构本身像艺术,同时软件工程作为一个新兴领域很多概念和方法仍在不断的演进,架构师的工作模式以及工作范围并没有约定俗成的定义,在各个行业、企业都有不同的要求和实践。

本文主要结合新的趋势,讲述架构设计的演进趋势,与各位读者共同探讨交流。

软件架构为什么越来越复杂

在“软件架构师”这个词随着软件行业诞生的时候实际上是包含了美好的愿望的,就是希望软件的架构可以像大楼的架构一样稳定,可以像硬件一样固化住。这个美好的假定护佑了一代一代的软件人,大家希望像建筑师一样去设计好一个不变的架构来护佑整个软件,架构师希望自己设计出一个架构然后程序员可以按照架构去实现,护佑架构师不去写代码,因为建筑架构师也是不去砌墙的。

但是,软件行业毕竟不是钢筋水泥,钢筋水泥很硬,软件很软。软件从一出生开始就隐含着另外一个人们对它的期待:可变性。软件之所以称之为软件,就是要具备在特定的情形下进行可变的能力,这个特定的情形在软件领域被亲切的称之为“上下文”。软件的可变性的需求,是的软件不在是一个三维空间的物体,不再是堆积几个building block组成一个完美的产品。这个可变的需求是随着时间来有演变的,一个三维空间扩展为四维空间带来的复杂性就不可同日而语了。

Prototyping Building Blocks

我们做一下简单的对比:

  • 只要软件在运行,对软件就会有不同的需求提出来,软件的核心是可变性,对架构的要求是可演进性;而对一个建筑不会,对一个建筑来说,保持原有的不变性是核心需求,很少有三天两头需要调整建筑功能的需求。
  • 软件会存在多个版本同时运行的需求,新老版本还需要考虑兼容性的需求,针对可能已经存在几十年的系统进行兼容性保障也是常有的事儿;建筑不会同时存在,对一个楼进行改造后,原来的楼就不存在了。
  • 软件可以规模化复制,要考虑异构化的部署环境(不同的芯片,不同的内存,不同的操作系统),这在软件行业叫做跨平台(Cross platform),可移动性(Portable);但建筑不是,建筑在做设计的时候就已经明确了特定环境需求。
  • 软件架构的工作成果可度量性不明显,可实现性衡量滞后,验证标准不一致,在架构设计中考虑实施的部分比例不足(缺少开发视图等),架构落地困难;在建筑设计中,施工步骤及细则具有明确的指导规范;

从上面这些对比,就会发现软件架构与

软件架构为什么不好做

大家逐渐意识到,软件和建筑不一样,在早期类比了建筑行业的很多做法,随着软件规模的发展已经不在适合了。

  • 建筑架构师是大学培养的、建筑工人是不需要大学培养的。建筑架构师与建筑工人具备的技能集完全不一样。建筑工人的工作技能相对标准化,独立、可替代性强,2个不同的建筑工人的效率和成果不会差别太大;软件工程师的工作技能不太“标准”,急需要了解业务,还需要懂技术,入门门槛高,资深员工很难替代,水平不同的软件工程师效率可能相差10倍以上,这就导致做软件架构的时候对团队情况需要考虑很多,而很少有建筑师会考虑施工队伍的情况;
  • 建筑师不是从建筑工人发展来的,但软件架构师几乎都是从程序员、软件工程师发展过来的,这就导致软件架构师的技能领域与软件工程师有很多重叠的部分,软件架构师没有明显的界限,不会一觉醒来就变成架构师了,所以在转变过程中角色差异性是非常大的。但工程师大多数在软件领域解决的是“如何做”的的问题,通过代码实现一个功能解决的是类似算法的问题,算法应对的是数据量变化的问题,而架构应对的是需求变化的问题,这两种问题本质上是不同的,但刚进入架构师行列的程序员如果还是用解决数据量的方式去解决需求量的问题,就会有些手忙脚乱,有些人会发现这种差距,去补上技能的差异,但更多的是把问题变换为自己熟知的领域去解决,这会导致架构变形,丧失了演进性;
  • 有些情况,架构师没有做架构师的事情,更多的架构师承担的是技术领导的角色,但因为工作的特殊性,一般侧重于完成功能性需求的交付,对冰山下的非功能性需求视而不见或者完全无视,导致产品存在基本的安全问题,性能问题,架构耦合紧密进而硬化,无法扩展,团队对新的需求恐惧进而抗拒;架构脆化,不同模块之间有无法察觉的联系,导致修改一处引发多个模块出现问题;架构僵化,相同功能的产品架构以及实现无法重用等等问题;
  • 有的架构师闭门造车出门不合辙,架构师团队花费大量精力提前做“好”设计,然后交付海量的UML图以及成百上千页的设计文档,但里面大部分仍旧只是在解决面向汇报的问题,这些设计图直接丢给毫不知情的开发团队,然后置之不理,这样导致开发团队认为架构师“闭门造车”,架构师认为开发团队“能力不够”,架构没有落实并指导开发;
  • 架构要服务于业务,还要对业务进行软件领域的建模抽象,业务状态变了会要求软件建构做响应的调整,但是现实情况有时候没有按照架构设计调整开发团队,或者没有按照团队能力做架构设计,最终架构变成空中楼阁,看着很美,但永远是愿景和远景。

这些问题都会导致架构不好做,或者架构给人留下的印象不好,导致架构师都可能给人留下的印象不好。所以,要想做好软件架构,首先要理解:软件架构是复杂的,软件架构不但要支持当前功能的实现,还要考虑:

  1. 未来的演进性,如果一个架构在设计之初没有考虑未来的变化是不合格的架构设计,对架构做出合适的预设计是必要的;
  2. 团队开发的难易程度(技术架构),技术选型、协议设计等都是需要考虑的因素;
  3. 合适的性能考虑,不过度追求也不完全忽视,根据需求选择合适的花销合理的架构设计;

对软件架构师个人还要考虑:

  1. 软件架构是有专业的技能需要学习的,不要简单的认为软件代码写的好就是一个合适的架构师;如果你已经具备丰富的设计能力(例如掌握了设计模式),那应该追求架构模式上的突破,不断的让自己站在更高的角度看待自己的工作,甚至可以考虑不断的对自己的工作挑刺;架构师需要的是跨越不同领域融汇贯通的技能、知识和经验。跨不过去,是不会成为合格的软件架构师的;
  2. 丰富的编程经验很容易让你沉迷于细节而对开发者如何编写代码指指点点;在《敏捷教练:如何打造优秀的敏捷团队中》提到:如果你没有参与到项目的编程,开发者多半会无视你的编码经验。他们还会认为你越权并影响了他们的工作
  3. (准)架构师要尽量与团队一起工作,避免团队对你的设计视而不见听而不闻,为了避免细节的工作占据太多的时间导致架构师无法看护整个项目,有经验的架构师应该带一两个学徒,来不断提高学徒的能力来应对未来的复杂性;

软件架构的当下

软件架构本身涵盖的领域非常多,从整体上来讲,软件架构要回答的问题是:

要解决这些问题,我们的软件应该采用什么样的结构,这些架构的组成部分如何协作能很好的解决识别的需求,并能够通过较低成本的更改结构和变更协作方式来支持未来识别出来的需求。

软件架构={结构,协作}

简单来讲,软件架构考虑的架构元素之间的结构排布,同时还要考虑架构元素之间的交互关系,这会构成看起来是封闭的结构,但在这个整体之外还要考虑与外界的交互,对外提供客户价值,对内满足团队价值,降低维护和演进成本,这些都是软件架构真正的魅力所在。

架构的分类

  • 基础架构,我们从分布式领域以及嵌入式领域两方面看:

    • 在分布式领域,主要解决的问题是如何面对更大规模的资源调度协作,解决多站点的协同问题;
    • 在嵌入式领域,主要解决的问题是如何面对越来越多的设备接入处理,解决多节点接入的协同问题;
  • 应用架构:对逻辑元素进行识别并做合理的排布、设计交互方式;

    • 分层架构:把整个解决方案按照一定的逻辑结构进行分层,定义清楚每个层次要解决的问题,并逐渐递归下去,直到每个层次都清晰明了,每个层次有独立的职责,多个层次协同提供完整的功能,典型的分层架构例如OSI网络的七层模型非常具有指导意义,另外例如把软件分为表示层、逻辑层以及数据访问层,通过分层架构的主要目的是降低系统复杂度,通过层间依赖来隔离全局依赖;

      layer architecture
    • 领域驱动设计:按照领域的方式对应用进行战略以及战术建模,识别出合适的聚合、服务等,并据此识别出核心领域与支持领域,对领域上下文进行内外设计,划清模块边界,更好的降低耦合,降低实现复杂度;

    • SOA,面向服务的架构在企业级OP架构领域雄踞多年(1990-),主要目标是提供可复用的服务以组件来完成特定的业务功能,随着嵌入式领域计算能力的不断提升,SOA架构在物联网领域仍旧具有很强的生命力;

    • 微服务架构:与SOA不一样,微服务提供的并不是企业级的架构方案,而是应用级别的架构解决方案,它是云原生时代的架构目标,通过把复杂的系统拆分出更细粒度的微服务来降低实现的复杂度。

  • 技术架构:根据业务逻辑分析,选择合适的实现技术来提供更好的协作方式;

    • 事件驱动:事件的产生、通信、处理和持久化是事件驱动的核心机制。事件驱动有两种常见的模型,来打打降低软件模块直接的耦合,典型的如kakfa,能够非常好的支持微服务之间的事件流转,并且提供一个灵活的系统,能够适应变化并实时做出决策。借助实时态势感知功能,您可以利用反映系统当前状态的所有可用数据,来做出业务决策:

      • 通过采用pub/sub模型,事件的生产者负责发布事件,事件的消费者订阅事件来进行处理,生产者和消费者没有必然联系,通过系统进行流转;

      • 事件流模型不要求事件消费者订阅事件,它支持事件消费者随时读取流来加入到流处理中来进行处理;

        EDA
    • 微内核:最早应用于操作系统中的设计理念,

      • 操作系统中的微内核:与传统的宏内核设计不同,微内核设计只完成操作系统的必要功能,例如时钟中断、进程创建与销毁、进程调度、进程间通信等,其他功能例如文件系统,内存管理等都放在用户空间,由内核进行调度完成,提供了更加灵活的运行时能力;

        micro kernel architecture
      • 应用程序的微内核:也有称之为插件化设计的,通过构建系统的核心的基础运行能力,这部分通常是系统中不变的、与业务相关性不大的部分,而把变化的部分变成插件运行于核心基础运行能力之上,提供动态替换、加载业务模块的能力;

        plugin architecture
    • 服务网格(Service mesh):为了解决微服务架构的通讯性能、安全性等问题,Service Mesh架构提供了了通讯Proxy的设计模式式来把与核心功能需求无关的部分划入proxy中,这个proxy也被称之为边车(sidecar)。边车的机制给微服务机构的优化提供了可能性,通过边车机制,能够很好的捕捉服务间的通讯细节,对通讯模型进行建模进而找出性能瓶颈进行整体优化。

      microservice architecture

    • MVC:经典的架构模型,通过把系统职责拆分为模型、视图以及控制器来分离职责,应用广泛,这里不再赘述;

    • 反应式架构(Reactive):为了区别于Responsive 对应于前端设计的响应式架构,这里更推荐使用反应式架构设计。反应式架构的核心是:

      • 对用户有反应,以用户交互为核心的设计思维,对交互的性能提出了明确的要求

      • 对失败有反应,并能够在停用期间保持可访问性

      • 对变化有反应,在极端的负载条件下仍能够调整系统来支持更多的业务

      • 对输入有反应(例如事件驱动)。

        reaction architecture

      这对系统设计的非功能性设计提供了更多的概念支持,更好的提供了系统的韧性、弹性和自适应性。

    • 流水线(Pipelining),随着函数式编程的复兴,结合FaaS的趋势,流水线是的架构设计把复杂的事务处理过程分割成多个独立的环节,灵活的组织以及组装流水线节点来构造一个图结构(Graph)来完成事件的处理过程(可以结合事件驱动)。

当前软件架构提高的机会

总体来讲,当前软件架构领域领域可以发力提高的地方有:

  1. 面向未来的思考,如何解决更复杂的问题的前瞻性
  2. 当前的软件架构缺乏艺术性,千篇一律的架构设计丧失了软件的灵性,这点在云原生领域更是如此,无论是否合适都照搬一套
  3. 架构模式多年没有大的突破,架构更多的关注于解决实际问题而缺少高层抽象的思考
  4. 概念杂糅厉害,三板斧打天下
  5. 如何打破网络物理限制的约束,基础架构、技术架构以及数据架构、基础设施等的关联探索
  6. 通信成本与数据一致性的平衡探索
  7. 边缘计算与云计算的协同问题,海量设备、大数据的架构设计模式
  8. 去中心化节点架构的关系演变以及scale out能力

软件架构的未来趋势

架构不是一成不变的,架构的方法也一样,正如文首所讲,随着IT基础设施的不断变化,架构的方法论、实践都在不断的变化。

  • 对于云原生系统来讲,系统的韧性、可见性、可移动性以及可维护性更加显得重要,混合云的解决方案更是促进了系统设计优先级的重排
  • 统一的数据模型以及信息总线,企业私有的信息模型会逐步汇入整个软件生态,互联互通和互操作性是最迫切的需求
  • 对于嵌入式系统来讲,低成本、高运算能力、低功耗、小体积的架构设计是物联网时代的诉求
  • Dapr以及OAM给分布式系统带来了更加方便的选择,微软在过去的几十年中一直给开发者创造了无与伦比的开发体验,让我们拭目以待
  • GraphQL更加头角峥嵘,下一代的GraphQL设计也已经开始展露锋芒,会继续挤压Restful API的生存空间
  • 低代码、工作流以及决策自动化平台与DSL共存并逐步替换的模式开始
  • 模块化单体架构:单体架构作为历史遗产,必然长期存在整个软件系统中
  • “架构师电梯”:数字化进程中,架构师的角色越来越重要,架构师逐渐成为企业高级管理层与开发者的通讯纽带,企业架构会变为企业非常重要一部分,成为更加清晰的职业(而非为特定领域定制的架构师)

Architecture trend 2021

ref:

  1. 架构分层:我们为什么一定要这么做?
  2. 事件驱动架构
  3. 什么是微内核架构设计
  4. 软件架构模式
  5. Architecture Trends 2021
  6. 架构师电梯
标签:架构设计云原生反应式事件驱动DDD分类

更多文章请关注《万象专栏》