架构的问题

注:写于2011-08-22 上周为了做一个新项目的详细设计,我们组开了好几次技术讨论会议,一群人从周一讨论到周五,赶在周末到来前终于把详细设计给确定下来。现在所在部门的文化是强调干活之前要充分讨论,和自己想法有不同的观点都要挑战一下。这样做的好处是在会上PK完了,下去执行的时候每个人都不会再有什么异议,码代码时都不会再有什么想法和疑虑。不好的地方在于这样做太摧残身心。每次到会议室开会都是站在走进去,扶着墙走出来,眼冒金星,死伤脑细胞无数。IT民工伤不起啊。会议的节奏往往都很快,每个人都得把自己调整到很紧张的状态,在满屋子你来我往的争论中快速思考,PK别人也接受别人PK。这是一项考验脑力,体力和心理承受能力的活动。这对于像我这样习惯于呆在一个角落闷闷思考的人来说,一开始还真有点不适应。 发完了一番牢骚之后,在这里言归正传,谈谈对软件架构的看法。对于软件开发来说,架构这个词无处不在,对它的解释也是五花八门,对软件开发的每个细分行业,甚至每个公司,每种开发流程来讲,架构在特定的环境下都有其特定的含义。我个人对架构的理解是,作为动词,架构是从了解产品需求开始,到系统模块功能的确定,团队中开发人员任务落实这整个过程中的一系列思考活动,主要解决系统是什么样子,以及该如何实现的问题。作为名词,架构就是这种思考活动所得出的设计文档,系统结构图,以及每个开发人员大脑中对要实现系统清晰一致的蓝图。以此观之,上周的几次技术讨论,就是一次典型的架构过程。在这次过程中,一群人详细讨论了系统实现各个方面的问题,达成了对如何实现该系统的一致的看法。说到这里,还得感谢下这个PK文化。在这里需求可以PK,设计可以PK,代码写完后在code review时还可以PK一番。这就迫使每个开发人员不能只专注于自己所负责的模块,而必须像一个架构师一样,从需求开始就去全面地,详细地了解系统,思考里面方方面面的问题。如果把一个架构师的职责看做:作为一个团队的技术负责人,架构师需要深刻地理解用户需求,现实的条件和约束,在这基础上去做合理的设计,让合适的人做合适的事情,在最短的时间内打造出一个符合产品预期的,能容错,可扩展性强的系统,那么可以把架构师这些事情和问题,归纳为以下几个方面。  1.如何实现功能并适应变化。互联网上的产品,特别是优秀的,成功的产品,往往都是专注于几个核心功能,简单易用的产品。但产品所体现的简单性背后,是数不清的被废弃的创意,设计乃至实现。一个产品从构想到成功,一般都会经历从简单到复杂再回归简单的过程,这期间修改无数。从技术的角度来说,这就需要你的架构适应得了变化,经得起折腾。记得以前在51的时候,某次开会时有一个哥们扔出一个问题让大家讨论:“到底是功能优先还是架构优先?”做一个针对某功能某版本的架构很容易,但是做一个适应新增功能和功能变化,历经多个版本仍然屹立不到的架构却很难。在这方面,google的例子值得借鉴。早期他们针对遇到的数据处理问题抽象出了分布式存储和map-reduce等计算模型,并基于此打造出了一系列系统。有了这些系统,就像在公司的业务领域铺设了巨大的高速主干道,开发具体产品时只需要基于这些主干道修筑自己的特性分支,从而很快地达到目的。传说gmail当初就是两三工程师用几天时间做出来的产品。  2.系统的性能,可靠性和可扩展性,以及数据分析和挖掘问题。这些都是架构师和后台开发人员需要大伤脑筋的问题。在每一次设计,编码和运营时都要为这些问题纠结不已。基本上每次通宵加班或者半夜被叫醒,都和这些问题有关。最近看了myspace,QQ漂流瓶等产品在解决扩容和可靠性问题时所写的心得体会,每一个案例都看得让人唏嘘不已。 3.处理现实约束,沟通交流和让合适的人做合适的事情。处理现实约束是指在架构时需要面对的现有系统兼容,某个额外需求或者某种技术条件还不具备等问题。沟通交流则是指架构师在团队中需要保持一种敏感,通过及时的沟通和讨论,让整个团队思路保持一致往前走。而知道如何让合适的人做合适的事情则可以保证甚至加快项目进度,反之则可能在某个地方造成短板。 相对于前两个问题,这些问题不是核心,但解决不善却可能导致整个项目的溃败。在这些问题域里,经常发生一些由于没考虑好某个小细节而导致工期延误,返工重做甚至全部推倒重来的悲剧。 4.降低软件实现的复杂度。架构师在架构时应该有意识地抽象出问题域一系列通用的问题,为这些问题设计通用的解决模块,让团队全体开发人员复用。这属于软件可复用性的话题,一个合格的架构师必须在该领域深入钻研下去。  将以上观点应用到具体的案例上,可以以上周的后台服务器架构过程为例。在上周的讨论会议中,我们主要面对并讨论解决了以下几个问题。 1.兼容多种协议。我们后台需要同时给桌面client和web应用提供访问接口,而这两种前台的协议都是不一致的。为此需要设计一个协议层,来将client和web的协议转换成统一的协议,供上层业务逻辑使用。该问题属于第3类问题,即如何处理现实约束问题。在这个问题的处理中采用了统一协议和分层的方法。 2.数据库表的设计。可以说面向企业的互联网应用的开发,在这个方面遇到了很多新问题。对于传统的企业级应用来说,数据结构比较复杂,需要考虑多表连接的情况,但是数据量不是很大,不需要考虑分库分表问题,而且数据库表的设计以及SQL编写,已经有很多经验和方法的积累。对于一般的,面向个人的互联网应用来说,它的数据量很大,但是数据结构比较单一,数据库表的设计也不是很大的问题,采用简单的分库分表就可以解决。然而对于基于互联网的企业级应用来说,即需要解决大数据量的存储问题,也需要解决数据结构复杂引起的多表查询问题。好在我们这个项目目前来说数据结构不算复杂,主要的思路还是分库分表,然后采用数据冗余的方式,避免了多表查询问题。不过随着企业级互联网应用需求的日益增加,相信以后将会出现很多和数据存储相关的问题。这些问题应该归属到第2类问题,需要解决在满足功能的前提下如何解决大量用户存储的性能问题,以及可靠性和可扩展性。作为一个新出现的问题域,该领域的进展值得关注。 3.数据缓存的设计。因为一个后台服务器需要支撑成千上万人的访问,操作就必须是异步的,有了异步操作就需要有缓存。数据缓存是让每一个后台程序猿头疼不已的问题,每次在设计和编码时,一遇到缓存都需要有条件反射般的小心谨慎。在这些次讨论中,我们解决了几个缓存问题。一个是缓存设计过于精细,导致缓存管理逻辑过于复杂的问题。解决该问题的方法是牺牲空间来简化缓存管理逻辑。还有一个是缓存结构的设计。需要一个通用性好的,易于管理的缓存结构,作为一个组件提供给上层逻辑,减少上层逻辑的开发量和复杂度。这里面包含了第4类,即让软件易于实现的问题。 有种说法是,做技术有三层境界。第一层境界是看山是山,看水是水;第二层境界是看山不是山,看水不是水,到了第三层,看山又是山,看水还是水。刚毕业时,提到架构总想起设计文档上那一张张系统结构图,流程图,UML图。因为那些图画的简单明了,易于施工,于是以为架构是件容易的事情;工作几年后,轮到自己去设计或者参与设计软件系统,才发现这些简单明了的设计文档背后,需要有多少抽丝剥茧,细细推敲的思考,以及化繁为简的功力。其中的山水的高远和繁复,让人不免生出迷乱之感。由此看出我还处于第二种境界,艰苦的跋涉才刚刚开始。我还不知道第三层境界是个什么样子,不知道什么时候能够进入其中,一窥究竟。上周的最后一次会议,讨论完毕之后面对一白板的线条和文字,忽然生出有种感慨,觉得编程是做加法,而架构是做减法,加加减减之间,是需要一个人用一辈子去领悟的东西。

你可能感兴趣的:(架构的问题)