BPM 观点:在云中使用业务规则解答 Sudoku,第 2 部分: 将规则应用程序部署到云中

第 1 部分 中,我介绍一种解决 Sudoku 迷宫的混合方法,该方法将使用 WebSphere Operational Decision Management (ODM) 构建的业务规则与一种启发式的深度优先搜索算法相结合。在本专栏中,我将重点介绍如何在云上执行该规则应用程序。Web 应用程序能够利用将要部署到公共云中的规则引擎吗?如果能,我们将使用哪些规则集成模式?我们将部署哪些 ODM 组件?我们可期待获得怎样的执行性能水平?哪些挑战在等着我们?这些是本专栏希望为两个广泛使用的云产品回答的问题:Google App Engine™ 和 Amazon Web Services™。 本文来自于 IBM Business Process Management Journal 中文版

Raj Rao, 决策管理高级解决方案架构师, IBM

Rajesh (Raj) Rao在专家系统和业务规则管理系统方面有 20 多年的工作经验,在这期间,他应用业务规则技术跨越各个领域,比如制造、运输和金融业,来构建诊断、日程安排、资格证书和配置应用程序。他在 IBM 工作已经快 2 年了。他有 Artificial Intelligence 背景,感兴趣的领域包括 Natural Language Processing 和 Semantic Web。



2013 年 5 月 13 日

简介

本专栏描述一个个人的发现之旅,集成了两种领先的技术:云计算和业务规则管理系统。这两种技术都能迎合不可阻挡的变化力量:基础架构需求的变化和决策逻辑的变化。作为业务规则管理系统 (BRMS) 的长期研究者,我非常好奇在云上开发和部署基于规则的应用程序时需要解决哪些挑战。我们将 第 1 部分 中介绍的 Sudoku 规则集部署到云中,以证明在云上使用规则的可行性,还要特别注意理解云带来的部署和执行限制。规则维护和许可等其他领域不属于本文的讨论范畴。

云计算(在一个可扩展、共享的 IT 环境中部署基于网络的应用程序)在如今的 IT 领域风头正劲,因为与更加传统的应用程序部署模型相比,它提供了众多的优势。这些优势包括大规模可伸缩性、接近实时的可用性和配备,以及改进的成本管理控制。

云计算不仅对 IT 管理员而言代表着一种根本性转变,对架构师和开发人员也是如此。从开发角度上讲,特别有趣的是平台即服务 (PaaS),它以服务的形式提供开发环境。在 PaaS 模型中,云提供者提供了一个 计算平台,该平台通常包含操作系统、编程语言执行环境、数据库和 Web 服务器。这些服务是免费的或按即用即付模式提供。应用程序开发人员可在云平台上开发和运行他们的软件解决方案,无需担忧购买和管理底层硬件和软件层的成本和复杂性。此外,在许多 PaaS 产品中,底层资源会自动扩展,以满足应用程序需求。PaaS 的示例包括:Amazon™ Elastic BeanstalkGoogle App EngineMicrosoft® AzureIBM SmartCloud® Application Services。

使用 PaaS 模型构建的应用程序会在提供者的基础架构上运行,通过 Internet 从提供者的服务器提供给一般大众。此部署模型称为公共云。通常,公共云上可用的服务受供应商的设计和能力约束。考虑到这些限制,我很想知道是否可使用它们开发和部署规则应用程序。我们将使用哪些 WebSphere ODM 组件?规则应用程序应如何打包?这些是我即将在构建应用程序和编写本专栏时回答的问题。在这里,我们会探索如何将一个 Web 应用程序部署在两个具有免费每日配额的流行的公共云服务上:Google App Engine 和 Amazon Web Services (AWS)。


Sudoku Web 应用程序

Sudoku Web 应用程序为用户提供了一个进入 Sudoku 迷宫的界面,并调用服务器上的规则引擎。Sudoku Web 应用程序的目标很简单:

  • 该应用程序应通过 Internet 提供给一般大众。
  • 该应用程序应在后端采用一个规则引擎(使用 第 1 部分 中描述的规则集)来解决 Sudoku。
  • 该应用程序应是用户友好的。它应该使用一个基于 AJAX 的交互式前端来捕获 Sudoku 配置,显示解法和分步说明。

图 1 显示了该 Web 应用程序,可在 此处 找到它。插图的顶部给出了允许用户输入 Sudoku 数据或将此数据作为字符串导入的屏幕。底部显示了单击 Solve using Rules 后得到的解法屏幕。右侧的列表描绘了规则引擎使用的分步推理。单击任意列表项会突出显示与该推理步骤对应的单元格,显示目前位置推导出的 Sudoku 解法。

图 1. Sudoku Web 应用程序
Sudoku Web 应用程序

该 Web 应用程序是使用 Google Web Toolkit™ (GWT) 构建的,后者是一个开发工具包,用于构建基于浏览器的复杂应用程序。GWT SDK 提供了一组核心 Java API 和小部件。这些工具使开发人员能够使用 Java 编写 AJAX 应用程序,然后将源代码编译为可跨所有浏览器(包括用于 Android™ 和 iPhone® 的移动浏览器)运行的高度优化的 JavaScript。可在 此处 找到 GWT SDK 的简介和它在 Eclipse 中的安装和使用说明。我发现使用 Google Plugin for Eclipse 来开发 GWT 应用程序非常有趣。

如果使用 GWT,那么所有编码都将使用 Java、HTML 和 CSS 完成。应用程序代码划分为服务器代码、客户端代码和共享代码。GWT 将客户端 Java 代码和共享 Java 代码编译为可在任何 Web 浏览器上运行的 JavaScript。客户端 JavaScript 使用 GWT 远程过程调用 (RPC) 框架与服务器通信,这使 Web 应用程序的客户端和服务器组件能够通过 HTTP 交换 Java 对象。从客户端调用的服务器端代码被引用为一个服务,可使用 Java servlet 架构实现它。在客户端代码中,GWT 自动生成一个代理类来调用该服务,处理在客户端与该服务之间来回传递的 Java 对象的序列化。

将一个使用 GWT 构建的应用程序部署到 Web 服务器很简单。您需要做的是将 GWT 生成的客户端 HTML、CSS 和 JavaScript 文件复制到 Web 服务器。服务器端代码也可轻松地部署到一个 servlet 容器中,因为 GWT 编译器在一个标准 WAR 目录结构中创建输出。


规则集成

客户端代码通常由 GWT 处理,但更有趣的是在服务器端调用规则引擎的服务定义。此服务定义获取了 Sudoku 网格的一个字符串表示,使用它作为参数并返回一个 Sudoku 对象,该对象包含解法的网格,以及用于获得解法的试探法的分步说明。下面的清单给出了该服务定义。

/**
 * The client side stub for the RPC service.
 */
@RemoteServiceRelativePath("sudoku")
public interface SudokuService extends RemoteService {
 Sudoku solveSudokuUsingRules(String sudokuDataString) throws 
IllegalArgumentException;
}

此服务的服务器端实现调用了 SudokuSolver,后者(如 第 1 部分 中所述)使用一种结合了 WebSphere ODM 和深度优先搜索的混合方法来获得解法。服务器端实现如下所示。Sudoku 求解器和规则引擎是在第 16 行调用的。

1./**
2. * The server side implementation of the RPC service.
3. */
4.public class SudokuServiceImpl extends RemoteServiceServlet implements
5.  SudokuService {
6.	
7. public Sudoku solveSudokuUsingRules(String sudokuDataString) throws 
   IllegalArgumentException {
8.   // Verify that the input is valid. 
9.   String errorMsg = FieldVerifier.isValidData(sudokuDataString);
10.   if (errorMsg != null) {
11.       throw new IllegalArgumentException(errorMsg);
12.   }
13.
14.   SudokuWrapperNode solution = null;
15.   try {
16.       solution = (new 
     SudokuSolver(getServletContext())).solve(sudokuDataString);
17.   } catch (Exception e) {	
18.	  throw new IllegalArgumentException(e);
19.   }
20.	
21.   Sudoku sudoku = null;
22.   if (solution != null) {
23.      sudoku = solution.getSudoku();
24.   }
25.   return sudoku;
26.  }

请注意,Sudoku 类以及与它关联的所有类(包括组成执行对象模型的所有 Java 类)必须放在 GWT 应用程序中,因为会在客户端和服务器端上使用它们。此外,所有这些类都标记为可序列化,以便能够在服务器与客户端之间传输它们。

WebSphere ODM 为将规则集成到应用程序中提供了许多不同的选项。最通用的规则部署涉及到使用一个应用服务器。但是,这在公共云上并不是一个合适的部署选项,因为我们受到了供应商的平台和能力的约束。我们使用了一个嵌入式规则引擎,如图 2 所示,该规则引擎从一个 JAR 文件加载一个规则集,并在与调用应用程序相同的 JVM 中执行它。此规则集是使用 WebSphere ODM Rule Designer 或 Decision Center 控制台从 第 1 部分 中介绍的规则项目中导出的。请注意,在导出规则集之前,应该在 Rule Designer 或 Decision Center 中对它进行全面的单元测试。

图 2 应用程序架构
应用程序架构

SudokuSolver(关键的服务器端类)实例化一个 RuleEngine 类,后者将一个嵌入式 WebSphere ODM 规则引擎 (IlrContext) 用于它的执行。该规则集从一个与应用程序打包在一起的 JAR 文件加载。在执行期间,RuleEngine 使用 ServletContext 将规则集 JAR 加载为一项资源,如下面的代码清单中的第 17 行所示。RuleEngine 使用 WebSphere ODM API(第 31-36 行)创建 ruleset 参数,并执行嵌入式规则引擎。

1. public class RuleEngine implements IRuleEngine {
2.  private static final Logger	LOG	= 
   Logger.getLogger(RuleEngine.class.getName());
3.  private static String rulesetPath = "/WEB-INF/sudoku-rules.jar";
4.  private static IlrRuleset ruleset = null;
5.  private IlrContext context = null;
6.		
7.  public RuleEngine(ServletContext servletContext) {
8.	super();
9.	try {
10.		init(servletContext);
11.	} catch (Exception e) {
12.		…
13.	}
14.  }
15.		
16.  private void init(ServletContext servletContext) throws 
    FileNotFoundException, IOException {
17.	InputStream in = 
    servletContext.getResourceAsStream(rulesetPath);
18.	JarInputStream is = new JarInputStream(in);
19.	IlrRulesetArchiveLoader rulesetloader = new 
    IlrJarArchiveLoader(is);
20.	IlrRulesetArchiveParser rulesetparser = new 
    IlrRulesetArchiveParser();
21.	
22.	ruleset = new IlrRuleset();
23.	rulesetparser.setRuleset(ruleset);
24.	boolean parsed = 
     rulesetparser.parseArchive(rulesetloader);
25.	// Create the engine
26.	context = new IlrContext(ruleset);
27.		}
28.		
29.  public void run(Sudoku sudoku) {
30.	// Initialize the inputs
31.	IlrParameterMap inputs = new IlrParameterMap();
32.	inputs.setParameter("sudoku", sudoku);
33.	context.setParameters(inputs);
34.	
35.	// Execute the ruleset
36.	IlrParameterMap outputs = context.execute();
37.	context.reset();
38.  }
39. …
40. };

使用嵌入式引擎的一个缺陷是,无法执行规则集的热部署。换句话说,在规则更改时,必须从 Rule Designer 或 Decision Center 重新生成规则集,必须重新构建和重新部署 Sudoku Web 应用程序,新规则才能生效。因此,在规则频繁更改时,此部署选项不适用。在这些情况下,一个更好的选择是使用作为 WebSphere ODM Decision Server 的一个组件提供的 Rule Execution Server。Rule Execution Server 是一个执行规则的环境,提供了管理、性能、日志记录和安全性功能。它将规则执行委托给一个执行单元 (XU),后者可作为 EE Connector Architecture (JCA 1.5) 的一个资源适配器在 Web 服务器或应用服务器上运行,支持规则集的热部署。我们将探索哪些云产品允许使用此部署选项。

有了基本的 Web 应用程序之后,让我们将注意力转向选定的公共云基础架构上的部署。


使用 Google App Engine 部署 Sudoku 应用程序

Google App Engine for Java 支持使用标准 Java 技术构建的 Web 应用程序在 Google 的可扩展的基础架构上运行。一个与 App Engine 和 GWT SDK 捆绑的 Eclipse 插件简化了使用 GWT 开发 Web 应用程序和将它们部署到 App Engine 的过程。

App Engine 使用 Java 6 JVM 在一个受保护的沙盒环境中运行 Java 应用程序,该环境会隔离安全应用程序和服务。该沙盒对应用程序施加了一些限制;例如,一个应用程序不能大量生成线程或将数据写入本地文件系统。App Engine 对 Web 应用程序使用了 Java Servlet 标准。应用程序的 servlet 类、JavaServer Page (JSP)、静态文件、数据文件、部署描述符(web.xml 文件)和其他配置文件都打包在一个标准 WAR 目录结构中。App Engine 通过调用部署描述符中配置的 servlet 来处理请求。

只要不超过限制,App Engine 应用程序使用的资源都是免费的。超出这些免费限制的资源的结算可通过设置一个每日资源预算来控制,如 此处 所述。

安装 Google App Engine

可在 此处 下载 Google App Engine SDK for Java,并将它安装为 Eclipse 插件。该插件添加向包含 App Engine 项目的 Eclipse 工作区添加新项目向导和调试配置。如果使用此插件,那么可以使用一个开发服务器在本地测试和调试 App Engine 项目,模拟 App Engine 沙盒的限制。可在 此处 找到运行开发服务器的更多信息。

在 Google App Engine 上构建和打包应用程序

要构建 Web 应用程序,需要用 jrules-engine.jar 补充 App Engine 应用程序构建路径的默认库,如图 3 所示。

图 3. 将规则引擎 JAR 添加到构建路径中
将规则引擎 JAR 添加到生成路径中

但是,当为了执行而进行打包时,需要其他一些 JAR。为了通过许可检查,与您的 WebSphere ODM 安装捆绑在一起的 sam.jar 必须与应用程序一起打包。此外,将规则集作为一个 JAR 文件进行捆绑并将它放在 WEB-INF 目录中,以便规则引擎可以访问和加载这些规则。WEB-INF 目录中还包含 web.xml(它包含 servlet 映射)和 appengine-web.xml(其中包含 App Engine 设置)。图 4 显示了为部署而进行的打包。

图 4. 为执行而进行的应用程序打包
为执行而进行的应用程序打包

将应用程序部署在 Google App Engine 上

部署一个应用程序之前,您需要从 App Engine Administration Console 获取应用程序 ID。这是选择应用程序标识符的地方:在我们的示例中,标识符是 sudoku-rules.appspot.com。此标识符用在项目的 Google App Engine 设置中,如图 5 所示,以便将开发工作区与云应用程序相链接。

图 5. App Engine 设置
App Engine 设置

将应用程序部署到 App Engine 中涉及两个步骤:

  1. 使用 GWT 编译器编译应用程序,以便用标准的 WAR 目录结构生成编译的应用程序工件。
  2. 将应用程序上传到云,这使用插件提供的部署向导来完成,如图 6 所示。
图 6. 将应用程序部署到 Google App Engine
将应用程序部署到 Google App Engine

在 Google App Engine 上执行应用程序

部署之后,可以在 Internet 上通过在浏览器中输入 http://sudoku-rules.appspot.com/ 来访问 Web 应用程序。但是,在 App Engine 上执行 Sudoku 应用程序有一些严峻的挑战。规则分析和执行非常慢,解决大部分 Sudoku 配置花费的时间超过了 60 秒,而 60 秒是一个 App Engine 应用程序的响应限制。为了克服此难题,首先应该尝试升级运行应用程序的实例类。这在 App Engine 管理控制台的应用程序设置中配置,如图 7 所示。但是,即使是最强大的前端服务器实例类 F4(它具有一个 2400 MHz CPU 和 512 MB RAM),性能也不够高,大部分请求不能在分配的 60 秒内获得解决方案。

图 7. App Engine 中的应用程序设置
App Engine 中的应用程序设置

查看图 7 的大图。)

Google App Engine 提供了另一个称为后端 的执行模式,它们是没有请求最后期限的特殊 App Engine 实例。每个后端实例有一个惟一 URL,该 URL 通过将一个后端前缀添加到 URL 来形成:http://rule-engine.sudoku-rules.appspot.com/ 用于 Sudoku Web 应用程序。有 4 个后端实例类,如表 1 所示。如果使用了配置文件(WEB-INF 目录中的 backends.xml),那么我们可以使用 B2 类的一个 App Engine 实例。借助此后端,可以避免 60 秒的中断,Sudoku 解法可在应用程序运行几分钟后获得。但是,即使将它升高到 B8 级别也不会明显提升性能。这表明 CPU 或内存都不是性能瓶颈。似乎是 App Engine JVM 中的某个内在因素让规则执行的非常慢。

后端类配置内存限制CPU 限制
B1 128MB 600MHz
B2 (default) 256MB 1.2GHz
B4 512MB 2.4GHz
B8 1024MB 4.8GHz

使用 Amazon Web Services 部署 Sudoku 应用程序

考虑到我在 App Engine 上运行应用程序时看到了欠佳的性能,我将注意力转到 Amazon Elastic Beanstalk 上,该产品是 Amazon Web Services (AWS) 的一部分。可以将 Amazon Elastic Beanstalk 视为一个 PaaS 产品,它处理负载平衡、自动扩展和应用程序监视的部署细节。它利用了其他 AWS 服务,比如 Amazon Elastic Cloud Compute (Amazon EC2)、Elastic Load Balancing 和 Auto Scaling。Amazon Elastic Beanstalk 构建在常用的技术堆栈之上,允许在 Linux™ 上使用 Apache Tomcat 运行 Java 应用程序。

AWS 还为新用户提供了一年的 免费使用层,支持每月使用 Amazon EC2 Linux†Micro Instance 750 小时(613 MB 内存)。

安装和配置 AWS

AWS Toolkit for Eclipse 是一个用于 Eclipse 的开源插件,可帮助开发人员使用 AWS 开发和部署 Java 应用程序的 AWS 库和项目模板。它将 AWS Elastic Beanstalk 与 Eclipse IDE 相集成。

在创建 AWS 应用程序之前,需要注册一个 AWS 帐户,并为所使用的任何服务注册。Sudoku 应用程序仅使用 Elastic Compute Cloud (EC2) 服务,这是一个虚拟计算环境,可使用各种不同的操作系统和 Amazon Machine Images (AMI) 进行配置。我选择了运行 Tomcat 6 的 64 位 Amazon Linux。

AWS 工具包用于创建一个新的 AWS Java Web 项目,这会创建一个配置了在首选项面板中指定的 AWS SDK 和 AWS 凭据的 Web 应用程序项目,如图 8 所示。

图 8. AWS 配置
AWS 配置

查看图 8 的大图。)

在 AWS 上构建和打包应用程序

无需额外的编码,便可将 Sudoku 应用程序部署到 AWS 上。来自 App Engine WAR 目录的已编译的应用程序工件只需简单地复制到 AWS 项目的 WebContents 目录。部署的应用程序的打包非常类似于 Google App Engine 的打包,但 App Engine SDK 替换为了 AWS SDK。这些应用程序工件将打包到一个 WAR 文件中,然后可以将该文件部署到任何 Tomcat 服务器,包括 Amazon Elastic Compute Cloud 提供的服务器。

将应用程序部署到 AWS 上

AWS Management Console(一个用于管理云资源的基于 Web 的界面)用于上传和部署 WAR 文件,如图 9 所示。

图 9. AWS Management Console
AWS Management Console

作为应用程序部署配置的一部分,您需要指定使用的实例类型,类型的范围可能从微型(613 MB 内存,最多 2 个计算单元)到 High-Memory Quadruple Extra Large Instance(68.4 GB 内存,26 个 EC2 计算单元)。对于 Sudoku 应用程序,我使用了微实例(如图 10 所示,我发现它足以满足测试用途)。

图 10. AWS 部署配置
AWS 部署配置

跟以前一样,部署到 EC2 的 WAR 文件使用了一个嵌入式规则引擎。但是,您拥有使用 Rule Execution Server Java SE 部署的更灵活的选项。在 Java SE 平台上,执行单元 (XU) 被部署为一个简单的 JAR,WebSphere ODM 规则引擎池已经启用。通过将 Java SE 执行堆栈与 Web 应用程序打包在一起,可以利用 Rule Execution Server 的全面管理和监视支持。这使用了外部持久存储来存储规则集,这不是 Google App Engine 的选项,但是 AWS 的一个选项。为了维护与 App Engine 部署的对等性,我没有尝试使用此选项。

在 AWS 上执行应用程序

可通过在浏览器中打开 http://sudoku-web-env-hnyeth7e8i.elasticbeanstalk.com/ 来调用 Sudoku 应用程序。跟预期一样,应用程序的外观与部署在 App Engine 上的应用程序相同。但是,性能却是另一回事:AWS 上应用程序的性能比 App Engine 高两个数量级。甚至非常复杂的迷宫也能在几秒钟内解答出来!


结束语

Google App Engine 和 Amazon Web Services 提供的免费使用层使得开发人员和架构师都能够轻松地获得构建云应用程序的实用经验。随着这些云应用程序对智能决策制定的需求的高涨,与规则引擎集成的需求也在增加。本文展示了一个使用 GWT 构建的 Web 应用程序如何在执行期间利用规则引擎。文中还演示了如何轻松地将 Sudoku Web 应用程序部署到多个云平台上。您已经了解到,使用嵌入式规则引擎作为规则集成模式同时适用于 App Engine 和 AWS。我们还了解了哪些 WebSphere ODM 组件应该与 Web 应用程序打包在一起。

来自不同供应商的云产品在功能和限制上有很大差别。对于 Google App Engine,只能使用嵌入式引擎。但是,对于 AWS,您拥有更多规则部署选项,比如 Tomcat 上的 Java SE 部署。一般而言,与 AWS 相比,Google App Engine 牺牲了灵活性,换来了易用性。

在云上运行规则应用程序不是没有挑战。例如,我必须在 App Engine 中使用一个 “后端” 来执行规则。意外的是,AWS 和 App Engine 在规则应用程序的性能上具有显著差别。即使是对于最大型的应用程序实例类,Google App Engine 在 Sudoku 应用程序上也具有非常糟糕的性能,而 AWS 在最小的实例类上也能提供了敏捷的性能。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=929449
ArticleTitle=BPM 观点:在云中使用业务规则解答 Sudoku,第 2 部分: 将规则应用程序部署到云中
publish-date=05132013