专栏-打造面向构件的大型企业级应用


 2005-08-15 00:00:00       758

今天给你一粒米,明天给你两粒米,后天给你四粒米,如此这般,一个月后你有多少米?哈哈,大家都很熟悉这个入门级的游戏。软件也是这样。随着需求的增长、功能的变化、工期的延长,在你抬头一望之间,我们在课堂里能编写出来的小白兔一下子变成了异常可怕的怪兽,它有几百万个关节,每个都能自由转动360度!实际上,大型软件和小软件根本就是不同的物种,需要区别对待。最具挑战性的就是大型软件中,一方面要在需求多变的不可测性中,另一方面需要在容量、交易量的不断突破中,来打造一个长期稳定的应用架构。

在这一个环境中,我们的应用架构要同时支持多个方面相对独立的成长,即数据结构的成长、系统容量和性能要求的成长、以及业务逻辑的成长,从而打造一个可以成长的大型企业级应用软件。



数据结构的成长

我们曾经讨论过如何使用标签化数据来解开业务逻辑和数据结构之间的锁链。XML是标签数据的典型案例,不过标签数据并不一定要时刻通过XML一类的字符来表达。一般来讲,数据在跨系统的交互时才会通过XML来表达。通过标签化的参数传递,我们可以最大化的是数据结构与业务逻辑分离,让业务逻辑自动适应数据结构在一定程度上的成长和变化。

业务逻辑的成长

随着软件的应用越来越深入,系统越来越大,功能点也越来越多。如此复杂的系统,必须由掌握不同技能的人来共同完成,软件成了名副其实的“系统工程”,人员数量也成了软件复杂性的一个参数。现在On Demand这个词在软件业界已相当流行,那么Demander又是谁呢?是Business!软件的变化是瞬息万变的商业环境要求的,因为软件系统越来越成为商业运作的内部引擎;提供不出功能强大的、安全可靠的、支持分布业务和高数据量要求的软件系统,就只有“客户很生气,后果很严重”这个结果了。

确实,软件必须成长,业务逻辑必须成长,企业需要“活”的软件。

面向构件:否定之否定

纵观大型软件的系统架构的变化,竟能发现哲学!

从原始的一锅粥架构到垂直分割的结构化架构,是第一次“否定”。现在看来,根据功能把软件的“解决方案空间”进行“竖割”虽然耦合度较高,但这个缺点不能掩盖产生“竖割”的深刻原因--这其实是从用户视角对软件的“问题领域空间”分割的最自然方式。

之后,大浪淘沙,大型软件的系统架构告别了功能分解的垂直分割时代,步入了水平分割时代。这个时代和工业史上的“泰勒时代”有点儿象--从业人员从事他们最专长的工作。本质而言,大型软件的系统架构从以“问题领域空间”的结构为中心,变成了以“解决方案空间”的结构为中心。

那么下一步呢?我们预言,“否定之否定”的哲学规律将发生作用,迎来横切竖割兼收并蓄的大型软件的系统架构!那么,横切竖割兼收并蓄的大型软件系统架构如何设计呢?我们认为答案是面向构件。



面向构件:稳定性、灵活性

此时,软件从业人员依然从事他们最在行的技术,横切时代的优点完全保留了下来。同时,业务构件作为“将不同更小构件编织在一起”的“竖割”的单元,非常符合用户和业务专家的视角,他们可以用业务构件直接组装想要的应用,非常灵活。

这时,软件业界关于“3.0才开始可用”的“稳定原则”似乎不再是铁律--在你开发产品的1.0版本时,可以大量使用稳定级别在3.0以上的被构件化的软件资产,就可以使1.0版本的产品稳定程度相当高。

面向构件: 降低复杂度

面向构件的理想是屏蔽细节、降低复杂性。目前,面向构件方法主要被用来帮助控制大型系统开发的复杂度和风险,在开发的构造和部署阶段中提供一种以架构为中心(architecture-centric)和以重用为中心(reuse-centric)的方法。随着时间推移,面向构件方法将演变成所有软件--包括可执行代码、接口规范、架构、业务模型、完整的应用和系统--都成为个体构件,都可以通过跟现成构件组装(assembling)、适配(adapting)、“捆绑(wiring)”在一起完成不同目的。面向构件方法提出了完美的方法来划分业务域,面向构件方法能控制用构件组装大型系统产生的复杂度。这种方法有望将开发的复杂度降低(然后导致成本降低)到八十年代的水平,同时能满足目前的所有需求。



总而言之,通过面向构件的技术,把“黑盒子”、“梅花桩”变成了“积木”、“矩阵”,增加了软件的灵活性,降低了软件的复杂度,使企业的业务逻辑随需应变,和企业同步成长。

系统容量和性能的成长

“先让系统运行起来,然后让它运行得更快”,不知这算不算业界一条“事实上的标准”。不幸的是,在架构确定之后,想通过调整来获得性能可能为时已晚--至少对于大型软件系统来说,认为“性能只和编码有关”是极为错误的。

从本质上来说,软件性能是计算与计算资源的关系。如图4所示,它采用UML语法描述,“性能”是一个关系类。例如,一个小的桌面应用可能只分配到了PC中单个CPU的10%的计算资源,但由于它计算量较少,因此依然性能极佳;而一个大型互联网应用即使分配了1000台服务器资源,若没有处理好计算与计算资源的关系,其性能仍可能差强人意。



因此,软件性能问题,必定首先是架构问题。架构事关对如何组织软件系统、部件的选择、组装部件所需的接口、部件组成更大的子系统时需明确的行为、以及架构风格等方面的重大决定,它从根本上影响着计算和计算资源的关系--系统的性能。在一个大型的应用软件中,建立一个可以优化的架构是设计过程第一步要考虑的内容。

数据库性能优化

大家关注的大型互联网应用中,因为数据量大,交易量大,在有限的资源面前,性能成为一个不能回避的问题。应用系统往往采用了流行的操作系统、数据库、中间件产品等等,这些产品已经在数据和分布处理层上有许多优化措施。在一个大型数据库的查询中, 常常有80%的时间都是在数据库端使用的。从而,应用系统的实际性能效果,往往在数据库的设计和使用上。然而,关系数据库是一种逻辑描述语言,SQL语句本身的复杂度和计算复杂度之间没有直接关系:我们可以写一个很简单的语句把整个数据库都倒腾一遍!

在数据库的优化过程中,我们需要对相关的计算量有较多的考察。有一些大型企业级应用必不可少的“最佳经验”,可以与大家分享探讨:例如有效利用索引、进行数据分表、两级查询、代码表的缓存检索、预计算、结果缓存、以及数据本地化及复制技术等。

比如,索引是最常用的提高性能的手段之一,但是正确有效的使用并非轻而易举。比如,大家常常使用“like”动态查询和匹配,而关系数据库的优化引擎看到“like”就会放弃索引的使用。在大型的查询中,需要用其它条件利用索引减小范围才能用“like”查询。

再比如,有许多查询本身比较复杂,实时使用的时候一定会影响系统性能。还有一些查询,虽然比较简单,但是查询的人数巨大(比如房地产网的首页!)。如果我们把这些查询的结果预先完成,那系统的响应就会很满意了。

将性能策略构件化

面向构件的技术,就是通过构件的接口作为软件模块之间的契约,而把实现的细节加以保护。我们可以使用数据和计算的结果,而优化的工作可以在构件内的实现中逐步进行。 面向构件的设计原则,也正是重视使系统容量和性能不断成长的稳定的架构。同时,容量和性能提升的知识,也可以以构件为载体,不断的重用。

相关阅读: