文章
使用 Oracle Application Express 实际演示 SaaS作者:Steve Bobrowski 通过构建您自己的小型 SaaS 应用程序了解“软件即服务”体系结构的基本概念。 2007 年 8 月发布 无论您相信创造论、智能设计论还是进化论,进化都是一个不可否认的过程,几乎涉及到生活中的方方面面。在自然界,各物种通过进化在不断变化的环境中生存。而在商界,管理良好的公司通过发展业务运营来提高竞争力和收益。 目前,商业领域中一个最普遍的趋势是,向提供和使用“软件即服务”(或 SaaS)的方向发展。本文解释了 SaaS 的一些基本概念、优势和实现细节,提供了构建演示应用程序的教程,以便开发人员和用户可以更好地理解和利用这项新兴技术。 为何选择 SaaS?从广义上讲,SaaS 的概念并不复杂,即:客户通过互联网访问作为托管应用程序的软件。那么,这样简单的概念为何大受欢迎?考虑一个简单的示例,比较一家中型或大型企业在实现标准客户关系管理 (CRM) 应用程序时可能采用的两种不同方法:传统的、内建应用程序所有权模型与按需 SaaS(或应用程序订户模型)。 传统的应用程序所有权模型通常需要公司进行以下操作:
从客户的角度看,拥有传统 CRM 应用程序第一年的总拥有成本可能高达数十万美元,更不用说每年的后续维护成本了。从 CRM 应用程序开发人员的角度出发,潜在的客户群仅限于能够负担与拥有和管理其应用程序副本相关的高昂价格的公司。 让我们将上述方法与简便的 SaaS 方法进行比较。如果使用 SaaS 方法,公司只需订购 CRM 软件服务,而无需考虑需要进行访问的用户数量。公司不必购买任何特殊的硬件或软件,也不需要聘用员工来安装、配置、修补、监视并维护操作系统、软件和数据。而公司的用户只需使用廉价的 PC 将应用程序页面加载到标准 Web 浏览器中,然后进行自己的工作。这样,向用户提供 CRM 应用程序的公司的总成本将大幅度下降。例如,salesforce.com 的一个常用按需 CRM 解决方案 (Salesforce) 的销售价格仅为每年每用户 140 美元。从客户的角度出发,该底线十分引人注目(除非公司拥有数千位用户),订购一个 CRM 应用程序远比为应用程序的完整拥有权支付费用更加经济高效。 应用程序提供商也会在向 SaaS 方法转变的过程中受益匪浅。如果应用程序设计良好且可在成百上千位用户订购服务时轻松扩展,那么低成本的商用硬件和开放源代码的操作系统可简化 SaaS 应用程序的有利托管。通过将低成本传递给客户,软件提供商现在可以从新市场(例如,原来无法负担应用程序所有权模型的小型企业)获得巨大的销售潜力。 不选择 SaaS 的原因SaaS 批评者会指出,尽管 SaaS 可能是提供小型应用程序(这类应用程序不维护关键数据)的良好模型,由于以下一些重要的警告,SaaS 很难在行业应用程序方面获得成功:
注意,这些反对过早接受 SaaS 的正确论点都聚焦在两个主要概念上:信任和控制(或者说缺乏信任和控制)。但随着时间流逝和 SaaS 逐渐成熟,不断发展的标准商业准则和解决方案一定能够解决所有这些问题。因此,我们有理由期望,对使用 SaaS 的担忧将降至人们或公司随意将其所有资金都存入银行或其他金融机构时的紧张程度。 SaaS 就在我们身边CRM 应用程序仅仅是目前作为服务提供的、面向用户的业务应用程序的一个示例。在软件行业的每个领域都能找到无数 SaaS 示例:
适应还是保守随着越来越多的企业了解并意识到将标准业务应用程序的运营外包给 SaaS 提供商可以节省资金,来自传统应用程序销售的利润无疑会受到打击。如果您是一位应用程序开发人员,一定无法承担忽视 SaaS 的出现所产生的后果。但是,构建、托管和维护 SaaS 应用程序需要您的思维习惯从“应用程序开发人员”转变为“应用程序提供商”。您不但需要了解如何开发实现 SaaS 的高可伸缩性应用程序,还需要应对并克服应用程序托管和维护带来的挑战。 我在本文中用于演示 SaaS 设计的软件开发环境是 Oracle Application Express。为了能从本文中最大程度地受益,我建议您在 http://apex.oracle.com 注册一个免费的 Oracle Application Express 工作区,然后进行本文中的操作来获得一些实践经验。 注:如果您没有时间或耐心亲自实施本文中的步骤,可以在 www.dbdomain.com/saasdemo.htm 查看已完成的应用程序的实况演示。 元数据:动态安全性和定制的关键大多数人都会认同,成功的 SaaS 应用程序必须具备可伸缩性、多承租商(即,可通过一个安全、可定制的数据库模式满足多个“承租商”的需求)和易于配置等特性。 您即将构建的小型 SaaS 应用程序经一次部署即可供任意数量的承租商使用,而各承租商的运营基本上是隔离的,不会意识到他或她正在与其他人共享应用程序,并且也不会出现一位承租商的数据被泄露给其他承租商的危险。 一个可以满足既定目标的应用程序不会是传统意义上的、静态编译的应用程序;它在本质上必须具备动态特性。可以在运行时变化的参数化应用程序由元数据驱动。广泛接受的元数据定义是“关于数据的数据”。换句话说,外观和功能可以变化的多态应用程序使用元数据来描述应用程序在其执行期内任意给定时刻的运行时属性。 Oracle Application Express 是应用程序开发环境的完美示例,它使用元数据来获得应用程序在运行时的各方面信息。 Oracle Database Application Express 用户手册中介绍的 Oracle Application Express 如下所示: Application Express 引擎从存储在数据库表中的数据实时呈现应用程序。在创建或扩展应用程序时,Oracle Application Express 将创建或更改存储在数据库表中的元数据。然后,在运行该应用程序时,Application Express 引擎会读取这些元数据并显示该应用程序。 实践操作让我们通过构建一个最简单的 SaaS CRM 应用程序,将您刚刚了解的 SaaS 基本知识投入实践,并亲自体验您从上文中获知的一些挑战。 此应用程序演示了我所提及的 静态通用列数据模型,该模型用于支持承租商可配置的 SaaS 应用程序。您还可以考虑另外一种称为 三层数据模型的实现方法(参见边栏)。 此演示应用程序中使用的模式在图 1 中显示为 UML 类图。该模式的设计非常简单,这样您可以将精力集中在学习 SaaS 开发的概念,而不是了解复杂模式设计的复杂程度。 图 1. CRM 类图该模式中的第一个表为 TENANTS 表,它存储了虚拟 CRM 应用程序订户(承租商)的最基本信息:主键 (TENANT_ID) 和公司名 (COMPANY)。TENANTS 表中的数据与表 1 的数据类似。
Table 1. TENANTS 表存储 CRM 服务订户(承租商)的基本信息。需要了解的下一个表是虚拟 CRM 应用程序的主要应用程序表,即 CUSTOMERS 表。乍一看来,该表的列名和数据类型显得有些奇怪。CUSTOMERS 表具有一个典型的主键 (CUSTOMER_ID)、一个引用 TENANTS 表主键的外键 (TENANT_ID) 以及八个非典型通用 VARCHAR2 列,列名分别为 COL_2、COL_3……COL_9。究竟为何我建议大家使用这种表格设计而非具有一组标准列(如 ADDRESS、CITY、STATE 等等)的 CUSTOMERS 表?为了实现我们 SaaS 应用程序设计的两个目标 — 使应用程序的数据模型灵活适应所有承租商需求变化,以及使用单一的模式应对所有承租商 — 您不能使用通常以静态编译应用程序构建的标准化“通用”表格设计,而必须使用具有表的应用程序模式。这些表允许每位承租商根据需要动态定制和扩展数据模型,并且可以在应用程序运行时随承租商的需求进行有效地变化。下面的表 2 将有助于您对上述内容的理解。
表 2. CUSTOMERS 表存储关于每位承租商的客户的信息。注意,第一位承租商拥有两位客户:我和 Tom Kyte;同时,第二位承租商也有两位客户,分别是名为 Ellison 和 Gates 的著名企业家。对于每个承租商的每位客户,COL_2 和 COL_3 分别用于存储客户的姓和名,但这是两个承租商所拥有的唯一共同点。第一位承租商使用 COL_4、COL_5、COL_6 和 COL_7 存储每位客户的实际地址信息;而第二位承租商使用 COL_4 存储每位客户的电子邮件地址,且根本不使用 COL_5、COL_6 和 COL_7。(此图使用 "-" 表示空值。)因此,我们此处显示的是一个单独的表格,可以存储这个非常简单的演示应用程序的每位承租商的不同客户属性。 您可能会问的下一个问题是:“该应用程序如何为每个承租商确定 CUSTOMERS 表中各列(COL_2、COL_3……COL_9)的用途?”答案是创建一个表,在其中存储关于含有真实数据的应用程序表的元数据:在此演示应用程序中,元数据表为 TENANT_COLUMNS。TENANT_COLUMNS 表有四列(参见表 3):
表 3. TENANT_COLUMNS 表包含应用程序可在运行时用于变化应用程序表的元数据。注意,上表中第一位承租商的数据显示,CUSTOMERS 表中的 COL_2 存储每位客户的 "Last Name",COL_3 存储每位客户的 "First Name",COL_4 存储每位客户的 "Address",COL_5 存储每位客户的 "City",COL_6 存储每位客户的 "State",COL_7 存储每位客户的 "Zip Code"。同时,第二位承租商的数据显示,CUSTOMERS 表中的 COL_2 存储每位客户的 "Last Name",COL_3 存储每位客户的 "First Name"。但与第一位承租商不同,COL_4 存储每位客户的 "Email" 地址。我故意将上文中各列的标签置于引号中,以帮助您意识到这些标签是应用程序在运行时查询和使用的抽象元数据。如果一位承租商决定向表中添加新的元数据或更改某列的标签,应用程序将在运行时自动调整,无需对代码库进行任何修改。在每位用户注册使用虚拟 CRM 应用程序时,承租商的管理员可以使用设置向导,该向导有助于简化承租商对应用程序用途的定制。 CRM 应用程序模式中的最后一个表是 USERS 表。这个简单的表仅存储有关承租商用户(执行该应用程序进行工作的人)的最基本信息:主键 (USER_ID)、用户登录名 (USERNAME) 和外键 (TENANT_ID)。USERS 表中的数据与下方表 4 的数据类似。
表 4. USERS 表存储每位承租商的注册用户信息。要点:每位用户的 USERNAME 必须全部为大写字母,以便支持示例应用程序使用的用户认证模式。稍后在您构建应用程序时,我们会详细介绍这一点。 创建 CRM 应用程序模式现在,您已经了解 CRM 应用程序模式,可以使用 Oracle Application Express 构建应用程序的表和支持数据结构了。在 apex.oracle.com 上获得一个工作空间后,可以使用给定的工作空间名称和凭证创建一个 Oracle Application Express 会话。Oracle Application Express 主页显示三个主图标,通过这三个主图标,您可以使用工具开始构建应用程序。 对于您将创建的四个表中的三个,还需要创建一个序列(即,主键生成器)和一个相关的触发器,以使用序列号填充表的主键。利用 Oracle Application Express 的向导驱动的界面,可以轻松创建表、相关的完整性约束、序列和触发器。 要在一次操作中创建一个 TENANTS 表和所有相关的对象,单击 SQL Worksheet -> Object Browser -> Create -> Table 启动 Create Table 向导。
CREATE table "TENANT_COLUMNS" (
"TENANT_ID" NUMBER,
"TABLE_NAME" VARCHAR2(30),
"COLUMN_ID" NUMBER,
"COLUMN_NAME" VARCHAR2(30),
CONSTRAINT "TENANT_COLUMNS_PK"
PRIMARY KEY (
"TENANT_ID", "TABLE_NAME",
"COLUMN_ID", "COLUMN_NAME"),
CONSTRAINT "TENANT_COLUMNS_FK"
FOREIGN KEY ("TENANT_ID")
REFERENCES "TENANTS" ("TENANT_ID"))
ORGANIZATION INDEX;
要帮助实现性能的最大化并提高应用程序的可伸缩性,请确保每个表都有一个主键,并为所有外键创建索引。默认情况下,Oracle 数据库会为所有主键约束创建索引,但并不为外键创建。Oracle Application Express 在工具的 Utilities 页面上有一个非常有用的实用程序集,可以帮助您识别此类问题并提高应用程序模式的质量。例如,单击 Home -> Utilities -> Object Reports -> Tables -> Unindexed Foreign Keys 将显示所有没有基本索引的外键。 您可以使用 Oracle Application Express Object Browser 的 Create Index 向导轻松创建必要的外键索引。要想操作更方便,也可以使用 SQL Commands 页执行两个 CREATE INDEX 命令来完成该任务:
CREATE INDEX "CUSTOMERS_IDX1" ON "CUSTOMERS" ("TENANT_ID");
CREATE INDEX "USERS_IDX1" ON "USERS" ("TENANT_ID");
简单 CRM 应用程序模式的最后一个组件是一个程序包,即一个由过程、函数、全局变量和其他结构组成的应用程序编程接口 (API)。利用 Oracle 数据库,您可以使用 Oracle 的 SQL 专用编程语言扩展(称为 PL/SQL)编写程序包代码。您可以使用 Object Browser 的 Create Package 向导,或者使用 SQL Commands 页面执行 CREATE PACKAGE 和 CREATE PACKAGE BODY 命令,来创建 CRM 的程序包:
-- The CRM_PKG specification declares the package's API.
CREATE OR REPLACE PACKAGE "CRM_PKG" AS
g_tenant_id NUMBER;
FUNCTION get_tenant_id (p_username IN VARCHAR2)
RETURN NUMBER;
FUNCTION get_report_columns (
p_row_source IN VARCHAR2,
p_tenant_id IN NUMBER DEFAULT g_tenant_id)
RETURN VARCHAR2;
FUNCTION get_form_columns (
p_row_source IN VARCHAR2,
p_tenant_id IN NUMBER DEFAULT g_tenant_id)
RETURN VARCHAR2;
END;
/
-- The CRM_PKG body defines all package constructs.
CREATE OR REPLACE PACKAGE BODY "CRM_PKG" AS
FUNCTION get_tenant_id(p_username IN VARCHAR2)
RETURN NUMBER IS
BEGIN
SELECT tenant_id
INTO g_tenant_id
FROM users
WHERE username = p_username;
RETURN g_tenant_id;
END;
FUNCTION get_report_columns(
p_row_source IN VARCHAR2,
p_tenant_id IN NUMBER DEFAULT g_tenant_id)
RETURN VARCHAR2 IS
l_columns VARCHAR(1000) := 'Edit:';
BEGIN
FOR rec IN
(SELECT column_id, column_name
FROM tenant_columns
WHERE tenant_id = p_tenant_id
AND TABLE_NAME = p_row_source
ORDER BY column_id)
LOOP
IF(LENGTH(l_columns) > 0) THEN
l_columns := l_columns || ':';
END IF;
l_columns := l_columns || rec.column_name;
END LOOP;
RETURN l_columns;
END;
FUNCTION get_form_columns(
p_row_source IN VARCHAR2,
p_tenant_id IN NUMBER DEFAULT g_tenant_id)
RETURN VARCHAR2 IS
l_columns VARCHAR(1000) := 'ID';
BEGIN
FOR rec IN
(SELECT column_id, column_name
FROM tenant_columns
WHERE tenant_id = p_tenant_id
AND TABLE_NAME = p_row_source
ORDER BY column_id)
LOOP
IF(LENGTH(l_columns) > 0) THEN
l_columns := l_columns || ':';
END IF;
l_columns := l_columns || rec.column_name;
END LOOP;
RETURN l_columns;
END;
-- initialization block
BEGIN
SELECT tenant_id
INTO g_tenant_id
FROM users
WHERE UPPER(username) =
htmldb_custom_auth.get_username;
END;
/
如果您具有 3GL 编程语言的编程经验,CRM_PKG 的声明应该相当容易理解。文章写到这里,我不想解释 API 的每个方面,但要介绍一些有助于理解程序包的基本知识。在本文的后面部分,当您使用 Oracle Application Express 构建 CRM 应用程序时,我将在合适的地方进一步解释每个程序包组成部分的使用。
添加一些数据创建 CRM 应用程序之前,请花一些时间使用表 1 到 4 中显示的数据填充 TENANTS、CUSTOMERS、TENANT_COLUMNS 和 USERS 表。您可以使用 Oracle Application Express 的 Object Browser 页面(选择一个表,单击 Data,然后单击 Insert Row)或者以下 SQL 命令来进行该操作:
-- TENANTS
INSERT INTO tenants (company)
VALUES ('Mike''s Tires');
INSERT INTO tenants (company)
VALUES ('Joe''s Tires');
COMMIT;
-- CUSTOMERS
INSERT INTO customers (tenant_id, col_2, col_3, col_4, col_5, col_6, col_7)
VALUES (1,'Bobrowski','Steve','123 Maple Street','Springfield','MA','02001');
INSERT INTO customers (tenant_id, col_2, col_3, col_4, col_5, col_6, col_7)
VALUES (1,'Kyte','Tom','456 Elm Street','Reston','VA','01566');
INSERT INTO customers (tenant_id, col_2, col_3, col_4)
VALUES (2,'Ellison','Larry','lellison@aol.com');
INSERT INTO customers (tenant_id, col_2, col_3, col_4)
VALUES (2,'Gates','Bill','bgates@hotmail.com');
COMMIT;
-- TENANT_COLUMNS
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (1,'CUSTOMERS',2,'Last Name');
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (1,'CUSTOMERS',3,'First Name');
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (1,'CUSTOMERS',4,'Address');
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (1,'CUSTOMERS',5,'City');
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (1,'CUSTOMERS',6,'State');
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (1,'CUSTOMERS',7,'Zip Code');
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (2,'CUSTOMERS',2,'Last Name');
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (2,'CUSTOMERS',3,'First Name');
INSERT INTO tenant_columns (tenant_id, table_name, column_id, column_name)
VALUES (2,'CUSTOMERS',4,'Email');
COMMIT;
-- USERS
INSERT INTO users (username, tenant_id)
VALUES ('MIKE',1);
INSERT INTO users (username, tenant_id)
VALUES ('JOE',2);
COMMIT;
创建 CRM 应用程序所有应用程序模式数据结构和相关对象都已就绪,现在可以构建应用程序的第一个版本了。如果这是您第一次使用 Oracle Application Express 构建应用程序,您会对只需单击几下鼠标即可轻松创建 Web 应用程序而感到吃惊。 要启动 Create Application 向导,单击 Application Builder -> Create,然后执行以下步骤:
图 2. CRM SaaS 应用程序 Customers 报表页雏形提供特定于承租商的数据安全性您首先应该注意的是,Customers 报表页的初始版本显示了两个承租商的 CUSTOMERS 表记录,而这没有满足 SaaS 应用程序的安全性目标。要对此进行修正,您需要完成三个相关步骤:
创建 Oracle Application Express 用户要创建两个与在 CRM 应用程序的 USERS 表中注册的用户相对应的 Oracle Application Express 最终用户,完成以下步骤:
创建应用程序项应用程序端全局变量在 Oracle Application Express 术语中称为应用程序项,要通过存储应用程序例程频繁引用的变量数据项来减少数据库调用次数并提高应用程序的可伸缩性和性能,它十分有用。在 CRM 应用程序中,在使用应用程序数据时,几乎每个数据库调用都会使用当前连接用户的 TENANT_ID。因此,最好创建一个可以存储每个用户的 TENANT_ID 的应用程序项。
修改客户报表的查询要限制 Customer Report 针对当前应用程序用户显示的行,完成以下步骤:
测试特定于承租商的报表要查看更改并确认报表现在仅显示与特定承租商用户相对应的记录,完成以下步骤:
显示特定于承租商的客户报表列现在,承租商安全性已经得到满足,可以将注意力转向自定义应用程序的用户界面了,该界面是特定于承租商的。正如当前所示, Customers 报表页显示所有承租商的所有通用列,并使用通用列标签 COL_2...COL_9。首先,将报表修改为仅根据特定于承租商的偏好(作为 TENANT_COLUMNS 表中的元数据加以维护)显示特定的列,这通过以下步骤完成:
显示特定于承租商的 Customers 表单下一组任务将处理 Customers 表单(应用程序的第二个页面)最初版本中的几个问题。该表单仅使用通过承租商安全的 Customers 报表页面访问的行,因此没有需要解决的安全问题,但表单有几个用户界面问题需要解决。要显示 Create Application 向导构建的表单的初始版本,单击其中一个客户的 Edit 图标。Customers 表单应类似于图 6。 图 6. 未经修改的 Customers 表单首先,请注意,该表单显示了外键列 (TENANT_ID) 的输入域,以及所有通用列(COL_2 到COL_9)的域。无论使用该应用程序的承租商用户是谁,Oracle Application Express 都会显示表单的同一版本。要使表单中的域特定于承租商,您需要隐藏 Tenant Id 域,然后修改每个通用列所对应的项,以根据 TENANT_COLUMNS 表中的元数据有条件地显示。下面是操作步骤:
注意,表单中不再显示 P2_TENANT_ID、P2_COL_8 和 P2_COL_9 表单项,这是因为针对每个表单项使用了基于元数据的条件显示查询。 需要在表单上调整的最后一项内容是 Customer 表单域的标签集。与报表列标签不同,您需要费点脑筋来解决这个问题。首先,您需要为表单添加一个新的隐藏域,用于存储一组以冒号分隔的、特定于承租商的列标签,这些列标签可以通过调用 CRM_PKG.GET_FORM_COLUMNS 函数来检索。
图 8. Customers 表单的最终版本(包含第 1 个承租商的特定于承租商的列标签)如果您注销身份,再以 JOE 身份连接,并编辑一个客户,则新表单将类似于图 9。 图 9. Customers 表单的最终版本(包含第 2 个承租商的特定于承租商的列标签)实践总结这个使用 Oracle Application Express 构建 SaaS 应用程序的实际演示证明了几个值得回顾的关键点:
SaaS 应用程序托管和维护恭喜!如果您完成了本文前面部分中的步骤,那么您已经构建了第一个 SaaS 应用程序(虽然非常简单)。但现在,您必须关注另一方面:SaaS 的操作方面。请记住,SaaS 应用程序是托管解决方案,服务提供商必须支持它们才有希望获得大量承租商。SaaS 的可用性、可伸缩性和管理是下一步要考虑的事项。以下部分简要介绍了其中每个主题,然后继续讨论本文基于 Oracle 数据库的主题,以演示目前可用的实际解决方案。 可用性当客户使用 SaaS 运行任务关键的业务操作时,服务必须随时可用。在客户看来,如果应用程序随时都会中断(而不是在偶尔进行的定期维护时段才中断),那么 SaaS 的成本优势和便捷优势将变得毫无意义。因此,SaaS 提供商通常要承诺一个合法的服务级协议 (SLA),然后必须立即实现符合该协议所需的技术;否则,服务毫无疑问会失败。 SaaS 提供商可以承诺的正常运营时间主要取决于该提供商决定使用的硬件和数据库系统。图 10 展示了 Oracle 技术系列的某些关键特性,慎重的 SaaS 提供商通常会使用这些特性来帮助确保服务的可用性。 图 10. Customers 表单的最终版本(包含第 2 个承租商的特定于承租商的列标签)注意,图 9 特别演示了各个级别(包括硬件、软件和数据)的冗余如何有助于维护 SaaS 应用程序系统的可用性:
高级数据库特性(例如,ASM、Oracle RAC 和 Oracle Data Guard)并不是数据库系统中可以帮助维护高可用性的唯一特性。在更基础的级别上,例行的数据备份操作不会明显地降低客户管理日常业务运营所依赖的 SaaS 应用程序的可用性或性能。Oracle 数据库及其随附的恢复管理器 (RMAN) 实用程序为 SaaS 提供商提供了一组完美的综合数据库备份特性,包括在线(热)、增量和并行数据库备份。补充的 RMAN 数据库恢复特性(例如,在线表空间、数据文件和块级恢复)还可以在物理媒介故障使得计划最周密的冗余防御出现漏洞时,帮助确保 SaaS 应用程序的一般可用性。 但是,或许 SaaS 提供商必须考虑的最可能发生、最棘手的数据可用性情况是特定于承租商的数据问题。例如,如果您的 CRM 应用程序的承租商错误地删除了所有客户,并要求立即进行数据恢复操作,您该怎么办?当然,这种要求很不合理,由于一个承租商的错误,SaaS 系统的所有其他承租商都必须承受数据库恢复所导致的停机时间,并丢失已提交事务的工作。Oracle 数据库具有许多逻辑数据恢复特性,可以帮助 SaaS 提供商从不可避免的事件(例如,用户错误、故障批处理作业以及错误事务)中恢复。例如,在上述案例中,您可以使用 Oracle 数据库的易于使用的闪回事务查询特性来撤消错误事务的结果,并恢复表中特定于承租商的行,同时其他承租商可以继续使用应用程序及其基础表,而不会出现任何中断情况。 可伸缩性对于独立软件供应商来说,SaaS 在经济上并不可行,并且应用程序的性能也无法满足应用程序的客户,除非随着越来越多的用户订阅服务,该应用程序可以借助其底层系统设计进行扩展。要想获得成功,SaaS 提供商必须从头设计兼具吞吐量和性能的应用程序和支持系统。 用于 SaaS 实现的产品系列中的许多特性(无论大小)都可以作为一个整体对系统的可伸缩性做出重大贡献。例如,考虑与在 SQL 语句中使用绑定变量一样简单而完善的特性如何帮助提高 SaaS 应用程序的可伸缩能力,以获得较高的事务处理率。如果 SQL 语句的 WHERE 子句使用绑定变量(参数)和运行时值替代,则数据库系统将进行分析和优化,然后在内存中缓存编译的语句,以最小化执行重复调用语句所需的 CPU 和内存的数量。如果没有绑定变量,数据库系统会不断浪费大量 CPU 时间和服务器端内存,来代替标准事务处理一次又一次地重新编译实际上完全相同的 SQL 语句。 数据分区是大部分 SaaS 应用程序广泛用于提高可伸缩性的另一个数据库特性。分区是一个存储选项,可以在物理上分离一个表中的数据。例如,在 CRM 演示应用程序中,您可以使用 Oracle 数据库创建 CUSTOMERS 表,以便数据库在单独的分区中存储每个承租商的行。从性能和可伸缩性的角度来看,良好的分区布局可以帮助减少或完全消除承租商之间为了数据访问而进行的物理资源争用。从应用程序开发人员的角度来看,分区表和非分区表的逻辑结构完全相同,因此利用分区功能不需要额外技能。 SaaS 环境中的另一个特殊的可伸缩性考虑事项是,应该指出如何控制共享一个应用程序实例的每个承租商的资源使用。例如,一个非常活跃的承租商不应该长期占用数据库服务器的 CPU 时间,以至于影响到共享同一应用程序实例的其他承租商的体验。Oracle 数据库的资源管理器特性提供了一个巧妙的方法,可以让应用程序承租商公平地分区访问系统范围的资源(例如 CPU)。 如果您确定应用程序的底层机制高效且可伸缩,则利用负载平衡和网格计算等面向硬件的方法,连用户最多的 SaaS 应用程序都可以近乎无限制地伸缩。例如,您可能使用一个所有承租商用户引用的虚拟 HTTP 服务器来连接到 SaaS 应用程序。负载均衡器可以在用户不知情的情况下将页面请求重定向到中间层 Oracle 应用服务器来处理请求。反过来,每个应用服务器都连接到 Oracle RAC 配置中的特定实例。如果特定承租商的请求与特定应用服务器/数据库实例的数据库访问方式相关联,则每个承租商的数据将保留在特定数据库实例的缓冲区缓存中,这将在多个承租商之间进一步提高应用程序的可伸缩性。随着越来越多的承租商订阅服务,您可以向负载平衡配置中添加更多的应用服务器和数据库实例。 数据和应用程序管理管理 SaaS 操作中的数据和应用程序部署会遇到许多特殊挑战,提供商必须解决这些挑战才能获得成功。例如,考虑以下几个可能的情形:
应用程序的供应和维护也是 SaaS 提供商必须考虑的关键问题。使用 Oracle Application Express,许多常见的应用程序维护步骤都得到了简化。例如,一旦构建了 Oracle Application Express 应用程序,您就可以将其定义和支持对象打包到一个文件中,将文件上载到其他服务器,并使用向导在新实例中安装该应用程序。未来版本的 Oracle Application Express 还将提供一个支持对象特性,用于简化将更新分发和应用到现有应用程序的过程。 安全性考虑到安全性是采用 SaaS 的主要障碍之一,提供商需要向潜在客户证明已经采取了任何可能的措施来保护他们的数据。以下是 SaaS 提供商在设计安全性策略时应该考虑的几个方面。 首先,在管理关键客户数据的按需软件服务中进出的所有数据传输都必须加密,以保护数据的完整性。所有 Web 浏览器通信都应该使用安全的 HTTPS 协议(而非 HTTP),Telnet 和 FTP 访问应该禁用,而由 SSH 和 SFTP 取而代之,并且所有直接的 Oracle 数据库连接都应该使用加密的 Oracle Net 连接(通过 Oracle Advanced Security 选件启用)。 机密业务信息 (CBI) 的加密格式的物理存储可以在介质失窃的情况下帮助保护敏感数据。例如,假设 SaaS 提供商加密了 CRM 数据库中的敏感数据,然后备份数据库,并将备份磁带(而不是数据的解密密钥)远程存储在第三方存储设备中。由于所有关键业务数据都已加密,因此数据窃贼无法使用偷窃的备份磁带恢复数据库,也就无法查看机密业务信息。Oracle 数据库的 Advanced Security 选件具有一个称为透明数据加密 (TDE) 的特性,您可以使用该特性加密数据库中选定的列,并保护 CBI 以防止所有下游组件(备份、重做日志等)中的刺探程序。 毫无疑问,数据在宿主设备中遭到破坏的可能性是每个 SaaS 提供商必须考虑和解决的问题。一旦提供商实现、调试并验证了 SaaS 应用程序,生产服务的开发人员和管理员就没有充分的理由来证明后续的数据访问 — 换言之,一旦提供商部署了 SaaS 应用程序,则只有客户自己才能查看他们的数据。SaaS 提供商可以使用 Oracle Database Vault 来限制数据库管理员、应用程序管理员和应用程序开发人员的数据访问权。 结论这篇介绍性文章涵盖了大量与“软件即服务”(SaaS) 应用程序的设计、开发和托管相关的主题。此外,本文还介绍了
Steve Bobrowski 自 Oracle 数据库版本 5 开始一直使用该软件。他以前在 Oracle 工作过,还是 The Database Domain (dbdomain.com) 的创始人以及五本 Oracle Press 书籍的作者(包括《Oracle 数据库 10g 快捷版上机操作》系列)。Steve 目前是 Computer Sciences Corporation 的 SaaS 业务首席技术官。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||