作者:Richy Ho


本文介绍了从传统Web应用一步一步迁移到SaaS的历程。


我观察了多家企业从传统 Web 应用迁移到 SaaS 的历程,察觉出其中存在着一种模式。本文试 图将这模式描绘出来,并总结出从中学到的若 干教训。虽然讲解中以 J2EE Web 应用架构作为示 例,但同样的原理也适用于其他技术平台。

 

第1阶段:使用中的现有Web应用 在最开始,我们已经拥有正常工作的Web应用。我 们分析现有应用的功能,把各个实现类划分成适当的组 (见图1)。

 

saas软件开发教程java saas项目开发流程图_saas软件开发教程java


 第2阶段:将功能分散到单独的进程中去 我们分析各个功能,将它们拆分到不同的进程 (JVM)中。拆分要求是粗粒度的,各进程通过一个 Facade类暴露出服务接口,经由这些服务接口实现彼 此间的通信。服务接口可以是各种远程对象调用,也 可以是XML Over HTTP。Restful Web Service是服务 接口实现途径的事实标准(见图2)。

 

saas软件开发教程java saas项目开发流程图_客户端_02


第3阶段:将不同进程转移到不同机器上 为了进一步扩展,跨越单台服务器能力的局限, 我们将进程转移到不同的机器上。请注意可以是物理 机器,也可以是虚拟机器(见图3)。

 

saas软件开发教程java saas项目开发流程图_客户端_03


第4阶段:构建服务池 如果服务本身是无状态的,我们可以简单地 向服务池中投入(运行着同样服务的)更多机器, 横向扩展服务的容量。有必要使用一个网络负载均 衡服务器来平均地将工作量分散到池中的服务器上 (见图4)。

saas软件开发教程java saas项目开发流程图_缓存_04


当工作负载上升时,可以向池中投入更多机器去 增强服务的总体容量。云计算供应商提供了弹性的扩展能力,使我们可以更加迅速地伸缩 池的大小,更有效率地处理动态的负 载变化。

 

第5阶段:通过分区扩展数 据层 业务处理层扩展完毕之后,我 们发现数据层成了瓶颈。因此有必 要通过按照数据的键作分区,分散 数据访问的工作负载。构建分布式 数据库的典型技巧请参考本刊2010 年第1期的文章《NoSQL的模式》 (见图5)。

 

saas软件开发教程java saas项目开发流程图_saas软件开发教程java_05


第6阶段:加入缓存以降低服 务器负载 如果应用的读/写比很高,或者可 以在一定程度上容忍过时数据,我们 就可以增加一层缓存层,减少对服务 的实际访问量。客户端在向服务发送 请求之前先检查缓存。

 

我们需要维持缓存对象的新鲜 度。这方面存在很多方案,比如可以设定缓存对象在一定时间后过期;也 可以在后端数据发生变化的时候,明 确地发出请求,将相应的特定缓存对 象废弃掉(见图6)。 我们可以用本地缓存(位于客 户端所在的机器上),也可以采用 Memcached或者Oracle Coherence这 类分布式缓存引擎。

 

saas软件开发教程java saas项目开发流程图_Web_06


第7阶段:考虑对外公开哪些 服务 到了这个阶段,我们希望对外 公开一些服务,也许是服务本身就 是获利渠道,也许是为了更方便与 商业伙伴实现紧密的B2B集成。决 定暴露哪些东西,牵涉到非常多的 考虑因素,比如安全、可伸缩性、 服 务 水 平 协 议 、 使 用 情 况 跟 踪 等 (见图7)。

 

saas软件开发教程java saas项目开发流程图_缓存_07


第8阶段:部署服务入口网关 决定对外暴露哪些服务之后,我 们根据具体的决策配置专门的服务入 口网关,负责处理上面提到的那些问 题。大多数XML服务网关都具备了消 息验证、安全检查、消息转换、路由 逻辑等功能(见图8)。

 

saas软件开发教程java saas项目开发流程图_缓存_08


第9阶段:部署服务出口网关 我们不但对外提供服务,同时也 会消费其他人提供的服务。此时需要 部署一个服务出口网关,帮助我们完 成查找服务端点、提取服务策略等任 务(见图9)。


saas软件开发教程java saas项目开发流程图_saas软件开发教程java_09



服务出口网关的一项重要功能 是管理企业内部对外部服务提供者的 依赖。典型的安排是让出口网关持有 提供相同服务的服务提供者的一份列 表,列表中还记录了该服务提供者的可用性(availability)和响应时间等信 息。出口网关要负责按照我选择的指 标(如最便宜的、最可靠的、延迟最 小的等)将请求路由到适当的服务提 供者(见图10)。

 

saas软件开发教程java saas项目开发流程图_saas软件开发教程java_10


第10阶段:实现服务的版本 控制 服务在对外开放之后还会继续演 进。在理想的情况下,只需要改变服 务的实现,服务的接口保持不变,因 此不需要改动客户端的代码。

 

但现实往往没有那么理想,服 务接口或者消息格式都有可能需要 修改。在这样的情况下,为了保证不 破坏现有客户端,有可能要同时运 行多个版本的服务。也就是说,服务 入口网关必须智能地将客户端请求 路由到正确版本的服务实现上去(见 图11)。

 

saas软件开发教程java saas项目开发流程图_saas软件开发教程java_11


典型的解决方法是维护一个版 本矩阵,跟踪各版本之间的兼容性。 我们可以规定一些发布策略,比如小 版本号的变动必须保持向后兼容, 而大版本号的变动就不要求。利用 这样的兼容性矩阵,入口网关就能 根据收到的请求判定客户端的版本, 并将其路由到具有最新兼容版本的服 务器上。

 

第11阶段:将基础设施外包 给云提供商 购买和维护必要的硬件设备成本 可能非常高昂,使用中出现闲置的计 算资源更是浪费。闲置通常是不可避 免的,因为我们要按照负载高峰去配 备资源,所以非高峰时段就必然会出 现闲置。 为了更有效地利用计算资源,

 

我们可以考虑市场上的云提供商,比如,Amazon AWS或者Microsoft Azure。 将应用迁移到云上可能需要重 新设计,才能适应云环境的一些特 质,比如,要适应较高的网络延迟, 要计较带宽的成本,还要让应用程序 的设计适应数据库的“最终一致性” 模型。