云计算环境下的应用架构设计
作者从云计算环境下应用的特点出发,分析了在云计算环境下应用程序开发设计的一些新变化。根据这些特点,本文提出一个“自我感知应用”(Self-Sensing Application)的新概念,接着以Windows Azure平台为例阐述如何实现自我感知应用。
多年来应用程序开发者和架构师们都在努力设计一种既能够在功能上满足当前业务需求,又能够适应用户需求发生变化或者能够在可预见的将来适应环境变化的应用。尤其是在互联网领域,架构师都在努力让自己设计的应用具有比较强的扩展能力,能够跟得上用户不断增长或者出现突发请求的一些情况。在传统的Web应用设计中,我们在架构上一般采用基于多层架构的设计,在Web层中大量使用了负载均衡等技术。一般我们的处理方式都是在应用程序设计好之后,在应用部署的过程中事先把环境配置好,而应用程序在运行过程配置都是不变的。但是,随着云计算时代的到来,我们面对一些新的挑战,相应的应用程序设计方式随之发生了一些变化。我们首先从云计算的技术特点开始讨论应用的变化。
从技术角度看云计算的特点
毫无疑问,云计算是目前信息产业中讨论得最多的话题。虽然大家对于云计算还没有一致定义,但是对于云计算的一些特点,相关的服务模型等内容日渐趋于统一。在讨论云计算应用架构特点之前,我们先从技术的角度来讨论一下云计算本身的一些特点。
按需服务
云计算是一个把信息技术作为服务(IT as a Service)提供的一种方式。这种服务的概念都是从消费方(用户)角度出发,而不是从服务提供方出发考虑问题,因此,云计算要求按需服务,即用户可以根据需求即时得到服务。从这个角度讲,云计算就像我们公共服务中的自来水、电、煤气一样,集中供应并按需服务和计费。
资源池
云计算的一个好处是提高资源的利用率,而这一般需要通过共享的方式来达到这个目的。这里可以类比一下我们日常吃饭中的自助餐和桌餐的差别。如果需要共享就需要先把资源集中到一个公共的资源池中。根据这个资源池中资源的类别,我们把云计算的服务模型分为三种,即所谓的SPI模型,如表1所示。
表1 SPI(Software Platform Infrastructure)模型
高可扩展性
云计算平台的资源池相对于单个用户的需求而言是比较大的,因此考虑到会有大量不同用户共用一个资源池,他们之间的资源使用模式一般存在一定的互补性,所以对于某个用户的需求而言,云计算具有很高的扩展性。另外,云计算平台在做架构设计的时候,都会考虑到如何让用户可以平滑扩展他们的资源需求,比如计算资源、存储资源等。
弹性服务
弹性服务指的是云计算的资源分配可以根据应用访问具体情况进行动态地调整。也正因如此,云计算对于非恒定需求的应用,比如需求波动很大、阶段性需求等,具有非常好的应用效果。在云计算的环境中,资源的扩展方式可以分为两大类:一类是事先可以预测的,比如一些季节性的需求;另一类是完全基于某种规则实时动态调整的。无论是哪一种,都要求云计算平台提供弹性的服务。
图1 自服务、自动化和虚拟化之间的关系
自服务、自动化和虚拟化
与日常生活中的ATM等自服务类似,在云计算中自服务同样是降低服务成本、提高服务便捷性的一种途径。对于云计算服务提供方来说,自服务就要求提供尽量简单的用户操作界面,简化用户操作,降低用户使用服务的难度,只有这样自服务才能被用户所接受。而且由于是人机交互,因此服务响应速度的要求就会更高。所有这一切都需要通过后台自动化的方式才能实现,也就是说后台自动化是前台自服务的保障。因此从这个意义上来讲,自服务是目的,而自动化则是手段。虚拟化的本质是解耦,是一种把资源从硬件束缚中解放出来的方式,从而使得资源的动态分配成为可能。这几个概念的关系可以用图1表示。
云计算自服务一般是通过Web门户来体现,就像在亚马逊的云计算服务中,用户通过自服务门户预定需要的计算资源就像在其电子商务网站上订购一本书一样方便。自动化一般通过程序和大量自动化脚本来实现,使得前端自服务界面用户触发的操作后台平台能够自动化完成,并及时响应,从而保证良好的用户体验。
服务可度量
管理学之父德鲁克曾经说过一句名言:“如果你不能测量它,你就不能管理它”。云计算作为服务提供的方式,需要对服务进行度量。一般服务提供方和用户之间需要有一个服务水平协议(SLA)。这样对于私有云来说,可以根据服务情况进行内部费用核算。而对于公有云来说,服务可度量就是计费的前提,然后根据实际使用量来进行计费。
云计算应用的特点
从前面的描述我们可以看到云计算给应用程序带来的一些挑战,那就是应用程序如何在云计算环境下充分利用云计算平台的一些特点来更好地满足用户需求。云计算应用要能够利用云计算环境中可动态扩展的资源,构建一个具有弹性的高可用的应用程序。下面我们分别讨论一下云计算环境下应用程序的特点和要求。
自动化要求
自动化是人类的梦想,而计算机对自动化领域的发展有着巨大的影响,它极大地提高了工作和生产效率。在云计算环境下,自动化要求实际上是对计算工作本身的一个自动化改变。云计算的自动化可以赋予用户对平台基础架构的资源配置任务进行全面统筹的能力,并实现对资源的动态分配以提高管理效率、减少人为错误并加快用户对资源请求的响应速度。应用程序在设计的时候要能充分利用云计算环境的自动化特性,从而使得应用程序可以在很少或没有人工干预的情况下,自动适应需求的变化。
分布式计算
大部分云计算平台都是用廉价和标准的计算机硬件构成,然后通过云计算软件的方式在计算能力、可靠性等方面来达到传统的大型计算机的水准。也就是说在云计算环境下,资源池通常是通过分布式软硬件方式来实现。因此云计算应用程序的运行往往涉及到多个计算资源。无论是计算还是存储需求,应用程序一般都会涉及到多个节点,这样在设计的时候要考虑并行设计的思想或采用分布计算的方式。比如,有些云计算应用可以根据计算的要求,采用类似MapReduce的编程模型。
松耦合
无论是功能上还是性能上云计算对应用的灵活性提出了更高的要求。这就要求应用程序在设计的时候要考虑松耦合的架构。耦合度与灵活性一般是相反的,即耦合度越高灵活性越低,而耦合度越低灵活性越高。因此,在做云计算应用架构设计的时候,一般要追求松耦合的设计。比如,在做Web应用设计的时候,对于用户状态的保持就需要尽量采用无状态的方式来设计,这样应用程序的水平扩展能力比较好。
数据存储方式
在传统的应用设计中,我们一般采用关系型数据库来存储数据。但是在云计算环境下,尤其是对于互联网应用,存在两个需要面对的问题:一个是云计算环境下的数据量都比较大,传统的关系型数据库面临数据扩展能力的挑战;另一个是许多应用对于数据存储的要求更多体现在非结构化数据或者是半结构化数据的存储上面。因此,大多数云计算平台都会提供针对非结构化和半结构化的数据存储方式。这样应用程序的架构需要针对新的数据存储方式作出调整。
上面描述的一些应用特点对我们开发和设计应用程序会带来许多影响。一个是应用程序在设计的过程中不仅仅需要考虑操作系统平台或中间件级别的编程接口,还要针对其运行的云平台的接口来对应用程序进行设计。另外一个比较大的影响是有一些工作量从平台产品转移到了应用程序的开发设计人员。比如说,在采用半结构化数据存储的时候,开发设计人员需要处理数据的一致性问题。还有,在云计算平台上如果想要得到比较好的性能,开发设计人员往往还需要对数据的分区进行特别设计,或需要采用一些并行设计的算法等。
具有自我感知能力的应用
传统的基础架构或系统平台中的资源都不能动态配置,因此应用程序在设计的时候主要考虑自身的业务逻辑的实现。应用程序本身的监控和管理都是通过其他系统管理软件如System Center、Tivoli等来实现。有一些管理得比较好的应用程序,可以通过这些系统管理软件实现部分资源的动态调整。但是,这些传统的应用程序本身对底层平台的运行情况是没有任何感知的。随着云计算的出现,应用程序本身的自动化逐渐成为可能。我把这些具有运行环境感知功能的应用程序称之为“自我感知应用”(Self-Sensing Application)。
自我感知应用的出现是应用程序发展的一种趋势,是自动化在应用程序运行过程中的一种体现。在做传统应用程序设计的时候,我们把主要的精力都放在功能性的需求方面,但是对于一些非功能性的需求往往采用手工配置和采用第三方工具的方式来实现。云计算平台的出现使得计算平台的资源具有可编程的特性,因此我们在应用程序的架构设计中可以通过基础架构平台的一些接口来感知应用程序的实际运行情况,并可以结合访问情况对应用程序的运行资源进行动态调整,以实现完善的自动化程序运行。
云计算平台具有可编程的资源分配,因此我们还可以设定自动化的部署过程,也就是让应用程序可以自动化地完成应用程序的部署、升级等工作。自动化部署也是应用程序动态扩展的一个前提。这样当需要更多计算实例来处理更多的用户请求的时候,新的计算实例可以动态生成出来并自动启用。
自我感知应用是应用程序朝着成为具有独立、自治单元的方式发展的一种体现。应用架构师在做设计的时候,面对的是底层抽象的、几乎无限的计算资源,而不是传统意义上的物理资源。从另外一个角度看这种设计方式也是应用程序与底层计算平台松耦合的一种体现,从而使得应用程序不绑定具体物理硬件。云计算平台从底层提供几乎无限的计算、存储和网络资源,其上的应用程序就像一个个具有人工智能的独立单元,他们在完成自身业务工作之外,还能够具有自我管理和自我修复的功能。
Windows Azure应用程序的自我感知实现
对于一个自我感知应用而言,一方面它要能够感知底层运行平台的一些环境信息,另一方面它还需要一种机制能够把自身运行要求转递给底层运行环境。Windows Azure上应用程序由代码和基于XML的配置文件两部分组成。应用程序可以通过配置文件把自身运行要求传递给Windows Azure,确切地讲是提交给Fabric控制器。但是,应用程序如何才能感知环境的一些变化呢?加入配置文件更新之后应用程序如何才能得到通知并作出响应呢?这里就要用到Windows Azure提供的服务运行时编程接口(Service Runtime API)。
Windows Azure的服务运行时编程接口最常用的使用方式就是帮助应用程序了解应用服务和应用所在的Role实例的信息,包括:
- 它能够让应用程序访问在服务配置文件和服务定义文件中的最新服务配置信息。当配置文件的信息被更新的时候,服务运行时编程接口能够保证返回最新的配置信息。
- 它能够应用得到最新的服务拓扑结构,比如哪些Role实例在运行,每种Role类型有多少实例等。
- 由于Worker Role中的代码运行周期有点类似于有限状态自动机的处理方式,服务运行时编程接口能够帮助应用得到Worker Role实例的生命周期信息。
服务运行时编程接口可以通过两种方式使用。对于.NET托管代码,Windows Azure的SDK中包含一个名为Microsoft.WindowsAzure.ServiceRuntime.dll,当用Visual Studio新生成一个云服务项目时它会被自动引用。而对于本地代码,可以通过使用SDK中的头文件和库文件就可以用C来调用这个编程接口了。
服务运行时编程接口是应用程序本身用来得到自身及其运行环境信息用的,但是如果应用程序之外,比如说一个管理工具要得到指定应用程序的信息,那么一般需要利用另外一个称为服务管理的编程接口(Service Management API)。这两个编程接口在功能有重合的地方,它们之间的最大区别在于服务运行时编程接口在Windows Azure中运行,而服务管理的编程接口一般在Windows Azure之外运行,它更多的用在那些针对Windows Azure的管理工具开发当中。
结束语
云计算无疑已受到极大的关注,但是它还是一个相对较新的概念,相关的技术正处于快速发展的过程中。我们已经可以看到云计算对IT行业的硬件模型、应用模型和用户体验等方面带来了革命性的影响。从应用模型的角度来看,云计算平台的出现使得开发人员可以快速构建高可用的、可以几乎无限扩展的应用。随着云计算相关技术的进一步发展,它将使我们能够进一步简化开发自我感知应用的工作,另外非功能性的一些要求也将更多通过配置文件而不是代码来实现。
人们对于信息技术需求的发展始终没有改变,那就是追求可靠、便捷、易用的信息应用。当我们把一个冰箱连接到电源插座的时候,我们从来不会去考虑这个电力是从哪个发电站来的,我们也不需要成为一个电力专家来使用这个冰箱。云计算的出现让信息技术往这个方向更进了一步。我们认为应用程序将逐渐演变成具有自我感知能力的应用,成为一个能够根据平台环境和用户请求进行自我调整和自我修复的自治单元。也许不远的将来,整个互联网就像一台巨大的计算机,其上提供无限的计算资源和服务,人们使用其上的应用程序就像我们现在使用自来水、电力那样方便、自然。
参考文献
[1] David Chappell, Introducing Windows Azure
[2] Peter Mell, Tim Grance, The NIST Definition of Cloud Computing
[3] Alexander Lenk, Markus Klems, Jens Nimis, Stefan Tai, Thomas Sandholm, What’s Inside the Cloud? An Architectural Map of the Cloud Landscape, CLOUD’09, May 23, 2009, Vancouver, Canada
作者方国伟,软件架构资深顾问,目前在微软开发工具及平台事业部负责微软云计算解决方案的技术推广工作。曾先后担任IBM(中国)有限公司软件部资深软件工程师、微软企业和合作伙伴部制造业客户技术经理。