《Unity3D高级编程之进阶主程》第二章,架构(一) - 架构的意义

什么是架构?

架构每天都有人在耳边提起。架构到底是什么,却很少有人说的清楚。

网络上解释的,比如,软件架构是一个系统的草图,又比如,软件体系结构是构建计算机软件实践的基础,还有,软件系统架构是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。说的都对,但是阐述还是过于模糊,懂的人本来就懂不用看,不懂的人还是一头雾水。

===

‘架构’这个词太抽象,导致难以准确定义,而现在的大部分书本和文章中讨论的都是服务器端的部署图,所以大部分人一提到架构就觉得是几台机子放这里,放那里,装什么软件,用什么框架等等。

我希望能这通过这本书,引导人们将错误纠正过来。架构实际上无处不在,它是解决生活和工作中的问题的一种方案。至于其他方案,比如直接购买现成的,或者直接放弃也并不一定是错的,或者我们现在比较流行的外包以及部分外包,还有合作模式等,都是比较好的解决问题的方案,我们力求的是没有最好的,只有最好用的。

在软件系统架构中,架构承担了解决项目从研发到上线运营的方案,前端是用Unity3D还是Unreal还是HTML5,怎么用,是和UGUI一起用还是和NGUI一起用,UI里的事件系统如何做统一的处理,AI选择行为树还是状态机抑或事件型决策树,数据如何获取和存储,场景如何拆分,是否需要将资源分离出去,是长连接还是短连接,服务器端是用PHP还是Python还是C++,是全部使用关系型数据库还是加入Cache机制,网络协议是用 protocal buff 还是 json 还是 xml 或者使用完全自定义格式等等等。

这些项目中的每个子系统的决策方向,而子系统的决策方向,把它们合起来加入一定的关联性就构成了一个完整架构整体,每个系统、模块、组件都是软件系统架构中的一部分。

优秀的架构师,需要对每个子系统决策的方向要进行深思熟虑,不仅只针对单个系统的决策方向,还要结合其他系统以及整体系统需求的方向进行决策。

为了在架构设计中,更好的整理,更好的思考,更好的描述,更好的表达,才有了架构图这个东西。架构师把架构中抽象的系统、模块、组件画在图上用圆圈、方块和文字表示,让自己或别人能够更加系统的认识到架构的意图,和子系统的细节。

一个完整架构图会有很多细节的子系统、或者说子模块架构图,比如UML对象关系图就是一种,它描述了数据类之间的关系,把系统中对象模块用画图的方式描述清楚了,又比如部署图也是其中的一种,它把需要多少种服务器,分别起到什么作用,相互之间的关系描述清楚了,还有时序图,把系统程序调用的次序与流程描述清楚了。这些子系统的架构图合起来构成了一个完整的项目的架构图,最后才有了总体的架构图,把子系统架构细节略去,在不关心细节的情况下,描述各系统的合作方式,展现给人的是整体的解决方案,从宏观的角度下看整个项目的布局,让人一目了然。

为了让更多人理解软件系统架构的,我想把软件系统架构比喻的更切入实际生活一点。

软件系统架构可以理解为是软件程序的架子,和现实中的书架差不多,这个架子上有很多大大小小的格子,每个格子里都可以放固定种类的程序。架子有大有小,大的需要花费点去做,小的轻便快捷。

架子的大小是由做设计的设计师决定的,设计师根据客户的需求设计大小,假如放置的空间大,且需要承载的东西多,那么就往空间大的方向设计,能容纳更多的东西,能放置各种不同类型的程序,反之则做小一点,又快,又轻。

架子完成后要拿出去用,如果一有什么不同的情况就倒了或散架了就不算是个好的架子了,所以架子的好坏有几个方面的评估。

一,承载力。

书架上能放多少东西,能放多重的东西是大家比较关注的点。

对于服务器来说,当前架构能承受多少人同时访问,日均访问量能承载多少,是承载力的体现。

对于客户端来说,能显示多少UI元素,可渲染多少模型(包括同屏渲染和非同屏渲染),数据交互能达到多少量。

访问量承载太低,访问量一大就都卡在加载上,大家就不再有这个耐心来看你的产品,运营和宣传部门的导量效果就大打折扣。同样的,客户端渲染承载不了过多元素时,帧率过低,画面卡顿现象严重,产品就不会得到认同。

承载力是重要因素,但并非是唯一关键因素,这个世界这个社会讲究的永远是综合因素,一个点的好坏并不能决定全盘的好坏,而往往木桶效应里最短的那块木板才是。

二,可扩展度。

如果书架上只能放书,这个书架的用途就太单一了,花瓶不能放、箱子不能放、鞋子不能放、袋子不能放、衣服不能放,客户八成不买单。

架子适应不同类型的需求,添加不同类型的系统,不同功能的子系统,是非常必要的。

而且可扩展度的关键在于,在添加新的子系统后不能影响或者只能小量影响其他子系统的运作。假设添加了子系统后,所有系统都得重写或者重构,那就是灾难,前面花去的时间和人力物力精力全部成为了‘浪费’,这是我们不想看到的,因此可扩展度也是非常重要的考量标准。

三,易用性。

易用性是架构师最最容易忽视的一个点,有了完整的架构,但不好用,而架构师却还是一心在推动它使用,导致开发效率的下降是常有的。

这就好比,书架上要取个东西,要先输入密码,再打开门,再剥去袋子,拿出来,把袋子放进箱子,关上门,当放回书架上去时,则再来一遍以上这些所有步骤,实在是太繁琐,即使功能再多,承载力再好,使用者也无法承受这么繁琐的步骤,而且都是机械重复的,精力和注意力都损耗在了没有意义的地方。

易用性决定了架构的整体开发效率,程序员容易上手,子系统容易对接,开发效率自然就高,各模块各部件的编写只需要花一点点精力来关注架构的融合,其他所有精力和注意力都可以全部集中在自己的框架结构上,才能让各系统各尽其职将效率发挥到极致。

四,可伸缩力。

还是用书架比喻,假设我现在没有这么多书和东西要放,房子也不够大,我的书架是否可以折叠缩小到我需要的大小,是可伸缩力的体现。

这种智能书架可随时放大或随时折叠缩小的,那就是更好了。

从服务器端来说,需要急速导入大量用户时到做能承载几百万人同时在线,服务器可随时扩展到几千台,小到当访问量低到只有几十个人在访问时,服务器可缩减到就几台机子在运作,这样就大大缩减了服务器费用的开销,也就是可以根据需要而随时变更架构的承载力来节省成本。

从客户端来说,伸缩力体现在能适应大型项目众多人协同开发复杂系统,大成本消耗下的大作品,也能适应小项目1-3个人团队小而快速的开发,小成本小作品极速迭代。

可伸缩力看起来并不是关键的因素,很多时候伸缩能力成了种负担,甚至有的项目某些时期根本不需要伸缩力,只需要适应当前的特定时间的需求就可以了。不得不强调可伸缩力在架构中的关键位置,它是深入理解、设计架构的关键因素,是做出优秀的完整的架构的重要因素。

五,容灾力。

错误、异常、BUG常有,设备何时损坏我们无法预估。容灾力首先起到了不让产品彻底不能使用的作用,有备份方案自动启用,也同时要能够让我们及时得知到问题发生,以及问题的所在,通过EMAIL发送或者通过短信、电话方式通知维护者,并且记录并保存错误信息。

从服务端来说,容灾力包括,数据库容灾能力,应用服务器容灾力,缓存服务器容灾力,以及中心服务器容灾力,每个机子倒下了都需要通知相关中心服务器改变策略,或者监控服务器检测得知该服务器倒下了,更换成备用服务器或者直接更换链路。

从客户端来说,容灾力包括当数据发生错误时,同样能够继续保持运行而不是直接崩溃,当程序出错时,依然能够继续运行其他程序,而不闪退或崩溃甚至再次启动也不能使用的状况发生。所有出现的错误,都能及时的记录并发送到服务器后台存储成为错误日志,便于开发人员能都及时得到详细的错误信息,根据错误信息能够快速找出问题的所在。

架构这五项能力缺一不可,某项能力特别突出也不能决定整个架构的好坏,综合因素才是。哪一项比较弱,则问题会不断向该方向聚集,直到最终出现大的问题,甚至崩溃。
万物是相通的,木桶原理在各个地方都适用,木桶上一条板很长没有用,其他板都短照样撑不住多少水。说到实际工作生活中就比如,老板CEO是有局限性的,对公司的宏观架构多厉害多好多明智,下面的高管不给力,一切都是白费力气,高管再给力,小弟们不给力,还是一塌糊涂。一个点的好坏并不能决定整体的走向。契合我的架构理论,最宏观的整体架构,是由所有子系统的架构来支撑的,整体架构虽然比其他子系统的架构都更加重要,但再好的整体架构也并不能起到决定性作用。引申到战争中,也是一样,立于众多溃败下的一两场漂亮的以少胜多的精彩战斗,还是无法扭转全局,一个好的将军需要众多好的将士支撑,一个好的司令需要众多好的将领以及更多的好的士兵支撑。综合因素决定了成败,如何让所有的因素都朝着好的方向发展是所有架构师最终都需要思考和解决的问题。

感谢您的耐心阅读

Thanks for your reading

  • 版权申明

    本文为博主原创文章,未经允许不得转载:

    《Unity3D高级编程之进阶主程》第二章,架构(一) - 架构的意义

    Copyright attention

    Please don't reprint without authorize.

  • 微信公众号