架构设计的主要目的是为了解决软件系统复杂度带来的问题。个人感悟是:架构及(重要)决策,是在一个有约束的盒子里去求解或接近最合适的解。这个有约束的盒子是团队经验、成本、资源、进度、业务所处阶段等所编织、掺杂在一起的综合体(人、财、时间等)。架构无优劣,但是存在恰当的架构用在合适的系统中,而这些就是决策的结果。不要过分设计。
架构概念
软件架构指软件系统的顶层结构;框架是面向编程或配置的半成品;组件是从技术维度上的复用;模块是从业务维度上职责的划分;系统是相互协同可运行的实体。
软件架构指软件系统的“基础结构”,创造这些基础结构的准则,以及对这些结构的描述。
软件模块(Module)是一套一致而互相有紧密关连的软件组织。它分别包含了程序和数据结构两部分。现代软件开发往往利用模块作为合成的单位。模块的接口表达了由该模块提供的功能和调用它时所需的元素。模块是可能分开被编写的单位。这使它们可再用和允许人员同时协作、编写及研究不同的模块。
软件组件定义为自包含的、可编程的、可重用的、与语言无关的软件单元,软件组件可以很容易被用于组装应用程序中。
高性能
性能是软件的一个重要质量属性。衡量软件性能包括了响应时间、TPS、服务器资源利用率等客观指标,也可以是用户的主观感受(从程序员、业务用户、终端用户/客户不同的视角,可能会得出不同的结论)。
在说性能的时候,有一个概念与之紧密相关—伸缩性,这是两个有区别的概念。性能更多的是衡量软件系统处理一个请求或执行一个任务需要耗费的时间长短;而伸缩性则更加关注软件系统在不影响用户体验的前提下,能够随着请求数量或执行任务数量的增加(减少)而相应地拥有相适应的处理能力。
但是,什么是“高”性能?这可能是一个动态概念,与当前的技术发展状况与业务所处的阶段紧密相关。比如,现在在行业/企业内部认为的高性能,站在5年后来看,未必是高性能。因此,站在架构师、设计师的角度,高性能需要和业务所处的阶段来衡量。高到什么程度才能与当前或可预见的未来业务增长相匹配。一味去追求绝对意义上的高,没有太大的实际意义。因为,伴随性能越来越高,相应的方法和系统复杂度也是越来越高,而这可能会与当前团队的人力、技术、资源等不相匹配。但是什么才合适的高性能了?这可能需要从国、内外的同行业规模相当、比自己强的竞争者、终端用户使用反馈中获取答案并不断迭代发展。
软件系统中高性能带来的复杂度主要体现在两方面,一方面是单台计算机内部为了高性能带来的复杂度;另一方面是多台计算机集群为了高性能带来的复杂度。
2 WHY 为什么需要高性能?
追求良好的用户体验;
满足业务增长的需要。
3 HOW 如何做好高性能?
可以从垂直与水平两个维度来考虑。垂直维度主要是针对单台计算机,通过升级软、硬件能力实现性能提升;水平维度则主要针对集群系统,利用合理的任务分配与任务分解实现性能的提升。
垂直维度可包括以下措施:
增大内存减少I/O操作
更换为固态硬盘(SSD)提升I/O访问速度
使用RAID增加I/O吞吐能力
置换服务器获得更多的处理器或分配更多的虚拟核
升级网络接口或增加网络接口
水平维度可包括以下措施:
功能分解:基于功能将系统分解为更小的子系统
多实例副本:同一组件重复部署到多台不同的服务器
数据分割:在每台机器上都只部署一部分数据
垂直维度方案比较适合业务阶段早期和成本可接受的阶段,该方案是提升性能最简单直接的方式,但是受成本与硬件能力天花板的限制。
水平维度方案所带来的好处要在业务发展的后期才能体现出来。起初,该方案会花费更多的硬件成本,另外一方面对技术团队也提出了更高的要求;但是,没有垂直方案的天花板问题。一旦达到一定的业务阶段,水平维度是技术发展的必由之路。因此,作为技术部门,需要提前布局 ,未雨绸缪,不要被业务抛的太远。
高可用
高可用基础是“状态决策”。本质上是通过“冗余”来实现高可用。
高可用保证的原则是“集群化”,或者叫“冗余”:只有一个单点,挂了服务会受影响;如果有冗余备份,挂了还有其他backup能够顶上。保证系统高可用,架构设计的核心准则是:冗余。有了冗余之后,还不够,每次出现故障需要人工介入恢复势必会增加系统的不可服务实践。所以,又往往是通过“自动故障转移”来实现系统的高可用。
可扩展性
核心是:封装变化,隔离可变性。
应对变化方案:
1)将“变化”封装在一个“变化层”,将不变的部分封装在一个独立的“稳定层”
2)提炼出一个“抽象层”和一个“实现层”。抽象层是稳定的,而实现层是根据业务进行定制的,当加入新功能时,只需要更改实现层,无须修改抽象层。
可伸缩性
当前大型互联网网站需要面对大量用户高并发访问、存储更多数据、处理更高频次的用户交互。网站系统一般通过多种分布式技术将多台服务器组成集群对外提供服务。伸缩性一般是系统可以根据需求和成本调整自身处理能力的一种能力。伸缩性常意味着系统可以通过低成本并能够快速改变自身的处理能力以满足更多用户访问、处理更多数据而不会对用户体验造成任何影响。
伸缩性度量指标包括(1)处理更高并发;(2)处理更多数据;(3)处理更高频次的用户交互。
其复杂度体现在(1)伸——增强系统在上述三个方面的处理能力;(2)缩——缩减系统处理能力;(3)上述伸缩过程还必须相对低成本和快速。
成本、安全、规模
低成本是架构设计中需要考虑一个约束条件,但不会是首要目标。低成本本质上是与高性能和高可用冲突的,当无法设计出满足成本要求的方案,就只能协调并调整成本目标。
往往只有“创新”才能达到低成本目标。1)引入新技术。主要复杂度在于需要去熟悉新技术,并且将新技术与已有技术结合;一般中小型公司基本采用该方式达到目标。2)开创一个全新技术领域。主要复杂度在于需要去创造全新的理念和技术,并且与旧技术相比,需要有质的飞跃,复杂度更高;一般大公司拥有更多的资源、技术实力会采用该方式来达到低成本的目标。
安全在技术角度上将包括功能安全和架构安全。1)功能安全-“防小偷”,减少系统潜在的缺陷(是一个逐步完善的过程,而且往往都是在问题出现后才能有针对性的提出解决方案,与编码实现有关),阻止黑客的破坏行为。2)架构安全-“防强盗”,保护系统不受恶意访问与攻击,保护系统的重要数据不被窃取(传统企业主要通过防火墙实现不同区域的访问控制,功能强大、性能一般,但是成本更高;互联网企业更多的是依靠运营商或者云服务商强大的带宽和流量清洗的能力,较少自己来设计和实现)。
规模带来复杂度的主要原因是“量变引起质变”。1)功能越来越多,调用逻辑越来越复杂,会导致系统复杂度指数级上升。2)数据容量、类型、关联关系越来越多。
规模问题需要与高性能、高可用、高扩展、高伸缩性统一考虑。常采用“分而治之,各个击破”的方法策略。
架构设计三原则
不断演化是架构发展的主旋律,而满足适合、追求简单是架构决策的重要依据。需求驱动技术的创新演化;技术反哺业务的发展升级。
1)合适原则
合适原则宣言:合适优于业界领先
失败原因:没有那么多人,却想干那么多活;没有那么多积累,却想一步登天;没有卓越的业务场景,却幻想灵光一闪成为天才。设计的目的不是为了证明自己,而是更快更好的满足业务需求。
2)简单原则
简单原则宣言:简单优于复杂
定位一个复杂系统中的问题总是比简单系统更为复杂
3)演化原则
演化原则宣言:演化优于一步到位
对于软件来说,变化才是主题。罗马不是一天建成的,架构也不是一开始就设计成完美的样子,然后可以一劳永逸的用下去。
各个公司的架构都是逐渐演进成当前的样子,在达到同样目的的过程中实现手段确并不完全相同,蚂蚁和阿里都进行了多地多中心部署的架构改造,但二者在诸如配置中心、跨ldc访问管控等方面都不尽相同,即使在蚂蚁内部也出现了后续实现推翻原始规划的情况。在多地多中心部署架构改造完成后,为进一步降低成本,避免大促活动中机器的浪费,又开始了弹性部署的改造,希望能够在大促高峰来临的前几个小时再临时增加服务器,等活动结束服务器就立即回收。等这个搞定,又开始在线离线混布的改造,进一步降低整体成本。
这些改造之所以一个接一个的能够实现,也在于使用的主要中间件和框架都是自研的,知根知底,可以快速迭代修改,如果是使用第三方的或者购买的,一方面可能非常贵,另一方面可能根本不支持,要重新设计改造部署所需的时间要远远大于自研的成本。
软件活动中没有“银弹”
在古代的狼人传说中,只有用银质子弹(银弹)才能制服这些异常凶残的怪兽。在软件开发活动中,“银弹”特指人们渴望找到用于制服软件项目这头难缠的“怪兽”的“万能钥匙”。
软件开发过程包括了分析、设计、实现、测试、验证、部署、运维等多个环节。从IT技术的发展历程来看,先辈们在上述不同的环节中提出过很多在当时看来很先进的方法与理念。但是,这些方法、理念在摩尔定律、业务创新、技术发展面前都被一一验证了以下观点:我们可以通过诸多方式去接近“银弹”,但很遗憾,软件活动中没有“银弹”。
布鲁克斯发表《人月神话》三十年后,又写了《设计原本》。他认为一个成功的软件项目的最重要因素就是设计,架构师、设计师需要在业务需求和IT技术中寻找到一个平衡点。个人觉得,对这个平衡点的把握,就是架构设计中的取舍问题。而这种决策大部分是靠技术,但是一定程度上也依赖于架构师的“艺术”,技术可以依靠新工具、方法论、管理模式去提升,但是“艺术”无法量化 ,是一种权衡。
软件设计过程中,模块、对象、组件本质上是对一定规模软件在不同粒度和层次上的“拆分”方法论,软件架构是一种对软件的“组织”方法论。一分一合,其目的是为了软件研发过程中的成本、进度、质量得到有效控制。但是,一个成功的软件设计是要适应并满足业务需求,同时不断“演化”的。设计需要根据业务的变化、技术的发展不断进行“演进”,这就决定了这是一个动态活动,出现新问题,解决新问题,没有所谓的“一招鲜”。
以上只是针对设计领域的银弹讨论,放眼到软件全生命周期,银弹问题会更加突出。
小到一个软件开发团队,大到一个行业,没有银弹,但是“行业最佳实践”可以作为指路明灯,这个可以有。