| 本文主要讨论基于单一共享应用程序实例的多租户模型。介绍在这种模式中重要 J2EE 工件的多租户资源共享、隔离和定制机制。还通过一个示例应用程序讲解如何设计基于 
                          IBM 中间件软件的支持多租户的 J2EE 应用程序。 在本系列的第二篇文章中(使用 
                          IBM 中间件实现 SaaS 解决方案,第 2 部分:启用多租户的方法),我们讨论了启用多租户的三种方法,即虚拟化、中介和共享。本文主要讨论第三种方法,介绍如何使用单一共享应用程序实例同时支持多个客户组织(即租户),实现经济有效性目标。我们要使用 
                          IBM 中间件开发一个经济有效、安全且可配置的多租户应用程序。我们主要关注多租户应用程序设计和实现的三个关键方面: 
                          资源共享机制:减少每个租户的硬件、软件和管理成本 安全隔离机制:防止租户之间的非法访问、冲突和干扰 定制机制:通过配置方法支持与租户相关的 UI、访问控制、过程和数据模型  为了便于读者理解,我们设计了一个示例应用程序 EasyOA,它应该有助于解释如何使用 IBM 
                          中间件产品(尤其是 IBM WebSphere Application Server (WAS)、DB2、Tivoli 
                          Directory Server (TDS) 和 WebSphere Process Server (WPS))实现多租户模型。 如图 1 所示,基于资源共享的多租户启用模式分为两类:1) 多个应用程序实例和 2) 单一共享应用程序实例。前者为每个租户提供专用的应用程序实例,这些实例在共享的硬件、操作系统或中间件服务器上运行。后者用单一共享应用程序实例支持许多租户,这个实例包含各种资源。这两种模式可以支持的租户数量差异很大。多实例方法用来支持几个(最多几十个)租户,每个租户可能有数百位用户,使用一组服务器。单一共享实例方法用来支持大量小型租户,租户数量常常是数百个、数千个甚至更多。图 1. 多个应用程序实例与单一共享应用程序实例模式 
    应该根据特定的应用场景和目标客户的需求选择资源共享模式。通常,大型企业喜欢多实例方法,因为这有助于避免与资源共享相关联的潜在风险。对于面向 
                          SMB 客户(他们的服务预订预算比较少)的大多数服务,为了实现规模效益,业务模型必须通过吸引大量客户增加收入,同时使用非常高效的可伸缩的多租户基础结构支持这些客户,降低每个客户的平均服务交付成本。在这些场景中,多实例模式是不合适的,因为每个租户带来的收入很少,不足以抵偿为租户分配专用的硬件/软件资源的成本。 
                         尽管多租户应用程序在经济有效性方面非常有优势,但是它们也面对许多难题,尤其是与隔离和定制相关的问题。 首先,应该在各个租户之间支持应用程序级隔离。尽管所有租户共享同一个基础结构和应用程序实例,但是从用户体验、服务质量 
                          (QoS) 和管理的角度来看,租户当然希望像专用租户那样访问和使用服务。因此,在体系结构设计的几乎所有部分都应该仔细考虑隔离,包括非功能性和功能性两方面,涉及安全性、性能、可用性和管理等。  第二,应该支持租户在运行时定制自己的服务,而不会影响其他租户。在过去,定制通常需要修改代码和重新部署应用程序。但是,这种定制模式在多租户服务环境中是不现实的。因为所有租户共享同一个应用程序实例,如果一个租户进行这样的定制,所有租户的服务都会受到影响,而且在更新期间可能会中断服务。随着租户数量的增加,中断会越来越频繁,导致非常严重的服务可用性问题。因此,一个租户在运行时的定制不应该影响其他租户,这是多租户应用程序的关键需求之一。 对于 J2EE/SOA 应用程序,有许多种可访问的资源,在用户界面、业务逻辑、过程/工作流和数据模型等层上还有各种运行时工件。为了设计非常高效的多租户应用程序,我们需要通过以下两个步骤小心地管理这些资源: 
                          识别出可以在租户之间共享的所有资源类型。估计通过采用共享机制能够节省的成本,据此确定它们的优先次序 
                          对于每种可共享资源,列出所有潜在的隔离和可配置点。针对不同的多租户场景,评估和总结最合适的隔离和定制方法 
                           表 1 简要总结这些重要的资源以及相应的共享、隔离和定制机制。在本系列的后续文章中,我们将详细介绍它们。表 1. 
                        多租户资源共享、隔离和定制机制概述 
 
                           
                            | 组件 | 共享的资源 | 隔离方法 | 可配置方法 |   
                            | 持久化数据模型 | - | - | - |   
                            | 数据库服务器(JDBC、SDO 等) | 数据源,连接池 数据库账户
 数据库/模式/表/缓冲区池等
 | 存储隔离:专用的表/模式或数据库,或共享的表/模式 访问隔离:通过专用数据源和连接实现 DBMS 级访问控制,或通过筛选器实现应用程序级访问控制
 | 数据库/表/模式 固定的保留字段
 扩展的子表
 XML 扩展字段
 |   
                            | 文件和 
                              I/O | 目录 文件
 | 专用的目录/文件 共享的文件,使用与租户相关的筛选器
 | 目录结构或文件格式 |   
                            | 目录服务器 
                              (LDAP) | 目录树 模式
 | 每个租户专用的子树 共享的树,使用与租户相关的筛选器
 | 目录树结构和模式定义 |   
                            | 业务逻辑 | - | - | - |   
                            | 身份验证/授权 | 组织结构/特权存储库 登录/授权模块
 | 根据持久化数据模型(LDAP、数据库等)隔离的存储库 扩展的感知租户的用户注册插件
 | 组织结构、角色、特权及其映射关系 |   
                            | 全局 
                              Java 对象 | 静态变量 单实例类的变量
 | 每个租户专用的(静态)变量,使用容器对象 | N/A |   
                            | 远程访问(套接字/Http、RMI、CORABA、JNDI、Web 服务) | 远程服务 URI、端口号、用户名、密码等连接参数
 | 专用的远程服务 共享的远程服务,把租户信息传播给远程服务
 | 连接参数 |   
                            | EJB | 有状态 
                              EJB 实例 数据源连接,实体 Bean 的表
 队列,发送者的 MDB 标识
 | 每个租户专用的有状态 EJB 实例、MDB、队列 共享的实体 Bean,使用与租户相关的筛选器
 共享的 MDB,在消息中嵌入租户标识信息
 | 共享的实体 
                              Bean 的保留属性 可定制的消息格式
 |   
                            | 日志 | 日志文件位置、内容、格式和配置 | 专用的日志文件 共享的日志文件,使用与租户相关的筛选器
 | 日志格式和设置参数 |   
                            | 缓存 | 缓存容器 | 专用的缓存容器 共享的缓存容器,使用与租户相关的筛选器
 | 缓存设置参数 |   
                            | UI | - | - | - |   
                            | JSP | 应用程序范围的变量(tag、usebean、applicationContext 等) 声明变量
 徽标、样式、布局等
 | 使用与租户相关的筛选器选择应用程序范围的变量 专用的声明变量
 | CSS、布局、图片等 |   
                            | servlet | 单线程 
                              servlet servletContext
 | 单线程 
                              servlet 使用专用的 servlet 使用与租户相关的筛选器选择 servletContext 变量
 | N/A |   
                            | 过程/工作流 | - | - | - |   
                            | BPEL 
                              过程模板 | 模板级属性、活动、链接条件等 | 专用的过程模板 共享的模板,在过程实例中使用与租户相关的筛选器
 | 过程模板的骨架 |   
                            | 人工任务 | 动作、任务 
                              UI 等 | 扩展动作,支持根据启动者的租户信息隔离人员选择机制 | UI 
                              元素和共享任务的设置 人员选择规则
 |   
                            | 业务规则 | 规则 | 专用的业务规则 共享的业务规则,使用与租户相关的筛选器作为规则参数
 | 业务规则的规则值设置 |  EasyOA 是一个为小型企业开发的简单的办公自动化应用程序。这个应用程序主要包含一个休假申请过程。职员可以通过这个过程提出休假申请和查询自己的休假历史,而经理通过这个过程批准职员的申请。管理员有权查看公司所有用户的操作日志。 
                         EasyOA 是一个典型的 J2EE 应用程序,它基于以下 IBM 中间件: 
                          图 2. EasyOA 的总体体系结构和多租户启用特性IBM WebSphere Application Server V6.02 IBM WebSphere Process Server V6.02 IBM Tivoli Directory Server V6.0 IBM DB2 V8.2  
   EasyOA 在设计时考虑到了支持多租户。如图 2 所示,支持的主要多租户特性如下: 
                          身份验证和授权说明如何设计组织结构和访问控制(特权)数据存储/访问模式。它们还在多租户上下文中增强了标准的 
                            Java Authentication and Authorization Service (JAAS) 
                            模块/过程。 公用 J2EE 工件说明如何通过一种基于隐式筛选器的机制区分租户,隔离和定制用户界面和业务逻辑的资源。 
                          持久化数据模型从隔离、安全性、定制和性能等许多角度,识别和评估用于数据存储/访问的所有多租户设计模式。 
                          业务过程说明如何按照共享过程模板模式,隔离和定制不同租户的人工任务或过程的人员/角色选择。 
                           本系列的第 4 部分将全面介绍这些特性的体系结构和实现。 多租户设计模式(使用单一共享应用程序实例同时支持多个租户)对于提高 Web 应用程序的经济有效性非常重要。在本文中,我们讨论了总体体系结构设计原则,以及使用 
                          IBM 中间件开发安全且可配置的多租户应用程序的相关技术。本文只是概述,后续文章提供关于这个主题的详细信息。学习
                        
                        获得产品和技术 
                          讨论下载  
                            IBM 产品评估版,试用来自 DB2®、Lotus®、Rational®、Tivoli® 
                            和 WebSphere® 的应用程序开发工具和中间件产品。  |