技术周|软件架构设计之道

大家有没有经历过这些场景,我们选用了一些看似很酷的技术,但上线后结果并不理想,技术人员总是加班去解决一系列技术问题,虽然总是再加班,但解决的都是业务无关的问题。又或者采用了看着很高大上的技术去处理并发但系统上线后发现并没有那么大的业务量(杀鸡用了牛刀),这些对企业来说都是浪费。

第一种浪费来自于技术层面的BUG,技术是首先是为支撑业务的,企业应为开发出的业务买单,而非为没有价值的BUG买单。第二种浪费是过度设计,通常是由于技术架构与业务架构、组织架构不匹配所导致,这两种浪费问题在我们日常软件开发中经常出现。

在我最近几年做架构设计相关的工作中,处理的业务系统包括及其复杂订单调度系统、业务规则多变的企业级管理平台,以及对并发和性能要求较高的收单系统,期间遇到了各种各样的架构设计问题,我不断思考有没有一种方法可以规避上述提到的两种浪费问题。

今天我分享下相关的经验,以便让大家在实际软件架构设计过程中有所收获,当然软件系统的好坏不仅仅与软件架构设计有关,通常还和软件研发管理,市场反馈等方面息息相关、但此文中我们只讨论软件架构设计这个变量。

一、软件架构的本质与目的


软件架构一词在每个人心中都有自己的定义,维基百科的定义是“软件架构是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。软件架构会包括软件组件、组件之间的关系,组件特性以及组件间关系的特性”。简单来说软件架构工作内容其实就是设计软件系统组件与组件(组件在这里是个统称,又或者是系统与系统,系统与模块)之间关系,为什么要设计组件与组件之间的关系呢,这就需要引出另外一个概念——软件架构的本质。

我们在日常软件研发过程中,会遇到各种各样的问题,比如梳理服务之间调用的关系,处理各种程序和中间件异常等,所以我们要通过一些手段尽量提前去规避这些问题,而软件架构就是解决这些问题的设计手段,所以软件架构本质就是为了解决软件开发过程遇到的各种各样复杂的问题,这些复杂的问题多种多样,总体上我认为可以分为两类,业务问题和技术问题。

如果只是为了解决业务或技术问题那就相对简单了,只选用高大上的技术或者我们完全基于需求分析人员的要求做开发就可以了,但软件架构设计的难点在于要在各种方案中去折中考虑,比如成本,研发人员数量,数据规模,性能等,而权衡的标准就是看能否快速高质量交付软件系统。这就引出了软件架构设计的目的——高质量的快速交付软件系统,为公司与客户实现降本增效。所以我们得出一个结论:技术是无法脱离业务孤立存在的,技术首先是支撑业务发展,要么为公司赚钱要么为公司省钱。下面我们就围绕软件开发的目的和本质来讨论如何解决业务问题与技术问题。

二、业务问题


软件架构设计中遇到的业务问题不只是要梳理复杂的业务规则或者画业务流程图,而是如何正确的定义业务问题,既客户真正的问题是什么,而理解业务往往是最容易忽略的点,业务不仅仅是需求人员或产品人员考虑的问题,协助需求人员对业务的梳理和抽象也是架构师的职责之一。业务问题往往比技术问题更加优先去解决,我们经常听到一句话“不基于业务场景去做架构设计都是耍流氓”。说的也是同样的道理,不理解业务我认为是导致架构设计混乱的主要原因之一,业务不定义清楚前期只能先靠程序员去coding, 后期出问题后再通过各种程序的技巧去规避这些业务问题,久而久之我们陷入加班填坑的状态,系统会慢慢演化为一个大泥球,最终崩塌掉。

举一个典型的例子,我们的业务人员希望在原有平台上增加一个数据分析系统,这样就可方便导出数据报表。某研发的同事负责设计了一套数据分析架构,考虑以后的扩展性引入了Flink,Kafka等等大数据相关技术,预估需要两个研发人员,4周的时间可以完成第一个MVP版本。技术上看起来比较酷,也解决了业务上的问题,但答案真的是这样吗?

 经过我们再次与业务人员再次沟通,其实业务人员只是想了解几个关键业务指标来监控日常订单的走势,对于其他业务指标并不是很关心。所以用4周时间建立一个大数据平台完全没有必要,最终我给出的方案是每天以邮件形式发送EXCEl格式的指标数据,预计投入1名研发,三天后可上线。显然第二个方案的交付速度更快,成本更低。所以对业务的理解深度不同,我们的架构方式也会不一样。

康威定律指出“组织沟通方式会通过系统设计表达出来”。组织架构也隐藏了我们对业务能力的划分,软件架构设计如果是逆康威定律那么导致的问题是业务架构与组织架构不匹配,最终也就无法交付出符合业务的系统。

也许一些做交付或者外包行业的同学会反对,因为我们不对客户“吹”,客户不会跟我们签合同,或者为了后期的维护费要不断给客户“挖技术坑”,但其实客户只要找一个专业的架构师去评审下就知道问题所在,相信我客户一定会这么做的,结果也一定是一锤子买卖,这也是国内做交付的企业被大家当成外包的原因之一。其实解决客户问题比挖技术坑更难,因为“同理心”的转变是反人性的。

软件设计过程中,如果不去理解业务,我们只能算是倒腾各种技术方案的架构师,所谓的“降本增效”就变得毫无意义,只能是满足了自己对技术快乐的追求,所以理解真正的业务问题是软件架构设计的第一优先级。

三、技术问题


只理解业务我们只能是一个业务专家,但架构师首先是一名优秀的软件开发工程师,需要具备极强的落地能力以及指导他人落地的能力,在我看来,“纸上谈兵的架构都是耍流氓。”所以深入理解各个技术应对的业务场景至关重要,我建议从以下四个方面考虑技术问题。

1、高可用


业务上是否具备高可用的需求,比如服务宕机后是否要有自愈能力,很多系统根本是不需要自愈能力的,只是出问题人工修复即可,这种情况下我们完全可以单机部署,只需要做好监控就好。

2、高性能


我们要理清业务的并发数是多少,用户可接受的相应延时有多大,如果只是在线人员为10个的系统,用微服务架构的意义在哪呢?

3、高扩展性


一般我建议考虑半年到一年内架构扩展性即可,我们可与业务人员沟通未来一年内业务增长量,比如只是临时用的系统,我们不必考虑任何扩展性,以最快的速度让系统上线。

4、其他


除了要考虑高性能、高可用、高扩展,我建议技术选型时还要根据CAP理论以及BASE理论去做技术选型,比如分布式锁的技术选型,要明白这个业务是AP场景还是CP场景,如果是CP场景就选ETCD分布式锁或Zookeeper分布式锁,如果是AP场景就行Redis分布式锁。

四、关于功利主义架构


业界不少架构师总结出了很多优秀的架构设计原则帮我们去做技术方案之间的权衡,比如“合适原则”,“简单原则”,“演化原则”等。不同的公司对这些原则的侧重点可能不同,初创公司可能是迭代业务为准,成熟型公司考虑的是1年内的业务扩展性以及稳定性,有没有一个通用的原则去满足不同公司阶段的场景呢,我认为是“基于功利主义去做架构设计”。

功利主义强调实际功效或利益去做决策,如果一个技术方案成本非常低,又能支撑业务发展,这就是一个好的技术选型。这样我们就可以把浪费在修复BUG上的时间转为做去技术创新,满足我们作为一名技术人员对技术理想的追求。
 
通过以上内容我们了解到软件架构设计的思想,但实践中有没有一套方法论或流程指导我们呢,答案肯定有,目前业界比较火的方式是使用DDD(领域驱动)的方式去做架构设计,DDD很好解决了业务定义问题,因为我们最终建立出的领域模型一定是与业务人员深入沟通的结果(比如采用事件风暴的方式),而非程序员的想象。

但要实施DDD需要团队成员每个人对DDD非常熟悉,单单是理解领域,仓储,事件,聚合等等这些概念就非常费劲了,所以DDD的落地并不简单。这又回到了软件架构设计的目的“降本增效”上,我们不必追求宗教式的DDD,所以我结合DDD的思想,总结出了一套架构设计过程,你可根据自己的项目对这个架构设计过程做删减。

五、架构设计过程


1、业务目标定义


我们可以拿张白纸,在上面写出如下问题的答案:

  • 1)客户在不用这个功能之前是怎么解决这些问题的?
  • 2)客户增加这个功能除了要解决问题1)还要解决哪些问题
  • 3)如果不能写出以上两个问题的答案,请询问相关业务人员。

2、业务模型抽象


  • 第一步我们要和产品经理或需求分析师一起建立业务模型。和DDD类似,我们可以采用将大的问题分解为若干子问题的方式,比如我们要向客户提供一个私有云的云计算解决方案,我们可以将整个方案分解为云计算管理平台(CMP),ISSA服务,PAAS服务,其中CMP可以继续分解为统一监控子系统,统一服务子,统一运营子系统。统一服务子系统内部就拆解为目录模块,自动化运维模块。注意这里拆解到模块级别就已经足够。这样我们就得到了整个业务功能的架构图。

  • 第二步开始梳理各系统之间模块之间的依赖关系,顺着数据流动过程画出模块之间关系依赖图。这样我们就将一个复杂的问题分解成为了一个个由简单模块组成的问题。

  • 第三步我们再次对每个模块再次进行分解,梳理模块内部的类之间的关系,以及类内部的行为,此时我们得到的是类似于UML类图。

经过以上分析我们得到了一个业务的全景图,系统之间关系图,模块关系图,模块内部逻辑图,由大到小,层层细化。

3、技术方案设计


根据步骤2的我们得出了具体的业务模型,接下来就是技术实现,我们可以采用DDD的分层架构,也可采用传统三层架构,对于DDD不熟悉的团队我建议采用传统三架构,采用失血模型实现业务,也就是所有的业务聚焦到service层。

此时我们还会面临架构风格的选择,比如单体还是微服务,对于小规模团队我建议还是单体优先或者分布式单体优先。

4、实施路线


架构最终是需要落地,所以我们还要制定具体实施的方式,对于一些大型的系统架构,需要分阶段交付,每一期最好可独立交付,想想我们国家的航天工程都是分好几期进行的。

六、结尾


由于篇幅有限只能写到这了,以上描述的架构相关的问题只是软件架构设计过程中的冰山一角,软件架构设计是一个综合类学科,包括了计算机科学,业务分析,哲学等多个领域。每个阶段我们对其认识也会不一样,这就需要我们不断学习,不断总结,一起做个终身成长的架构师吧。

技术周|软件架构设计之道

技术周|软件架构设计之道

关于九州云:

九州云成立于2012年,是中国早期从事开放云边基础架构服务的专业公司。公司成立九年,始终秉承“开源·赋能云边变革”的理念,完成了从中心云到边缘云解决方案的拓展和积累,建立了完整的“云+边”生态体系和解决方案。九州云已先后为运营商、政府、金融、能源、制造业、商业、交通、物流、教育、医疗等各大行业的企业级客户提供了高质量的开放云边基础架构服务。目前拥有中国移动、中国电信、中国联通、国家电网、南方电网广东公司、中国人民银行、中国银联、中国人寿、中国资源卫星、eBay、国际陆港集团、万达信息、东风汽车、诺基亚等众多重量级客户。

技术周|软件架构设计之道

点击原文,了解更多

技术周|软件架构设计之道