简介: 当一组工作项目被用于分配 WebSphere® Process Server 中的任务所有者时,许多组成员可能会尝试同时声明一个任务。在 V7 之前的版本中,避免一个并发异常的惟一方法是封装同步块中决定和声明任务的查询。本文提出一个新的方法使用查询表声明任务。
当一个人工任务分配给一组潜在所有者时,例如,WebSphere Process Server 中的 Everyone 或一个 Group 工作项目,组内的多个成员试图同时声明一个任务。在之前的 WebSphere Process Server 版本中,消除并发异常的惟一方法是封装同步块中决定和声明任务的查询(或使用 Java™ 5 中的可重入锁)。同步方法有一些缺陷,由以下原因引起的:
- 同步块在工作项目上的员工查询完成之前执行。这就导致了访问任务时所有线程阻塞,不仅仅是访问任务和工作组成员的用户请求阻塞。
- 同步块被限制在一个 JVM 上,请求被路由到集群中的另一个节点并引起接收节点中的并发异常,这种可能性仍然存在。
在 WebSphere Process Server 早期的版本中,申明人工任务方法是分两次调用,首先是查询数据库中的可用任务,其次是声明第一次查询返回的任务。这两种方法都是围绕着同步块的,这意味着每次只有一个线程可以执行这个代码,如图 1 所示。
在 WebSphere Process Server V7 中,声明任务的方法是用一个查询表,并结合早期用于消除同步块需求的查询和声明方法。这提供了多线程并发访问数据库中的人工任务,如图 2 所示。
在本文中,您将检查新方法同时使用同步方法和查询表方法,证明新方法确实如宣传的那样,不会引起某种形式的并发异常。
为了证明新方法确实如前面所说的那样,您将构建一个样例应用程序,突出该功能所需的组件。应用程序不应该是一个已经实现的产品,而应该是一个说明使用查询表方法申明的样例。
假设您已经安装了 WebSphere Integration Developer V7(以下简称 Integration Developer)。您可以下载一个 项目交换文件,其中附有样例所需的所有代码,除了代码之外,还需要如下描述的附加软件:
- 下载 WebSphere Integration Developer 查询表插件。
- 当应用程序在服务器上运行时,使用 Apache JMeter 测试并发性。
应用程序将运行在 WebSphere Process Server V7 测试环境中,测试环境是 WebSphere Integration Developer V7 安装的一部分。当您安装了查询表插件之后,像 PA71 Getting Started 文档描述的那样,您可以查看查询表构件,它是项目交换的一部分。JMeter Test Project 也是项目交换的一部分,在本文后面在本地服务器上测试并发性时将会用到。
创建这个解决方案的第一步是在 BPEDB 中创建补充表 SUPLDATA。 BPEDB 表包含补充数据,说明使用查询表方法声明的分类功能。SUPLDATA 表含有申明任务时区分任务优先级所需的数据。该表强调了任务数据和使用查询表的补充数据的连接。在下一小节中,将基于此表创建一个查询表,用于声明一个任务。
SUPLDATA 表由连接表中数据和 TASK 视图中任务数据的列构成,还有申明时安排任务次序所需的列。REFID 列是一串序列号,是在创建任务时 JMeter 测试案例所生成的。它们被放在任务实例的客户属性中,在进行补充数据清理时用于引用补充数据行(任务完成时)。
以下步骤帮助您创建 SUPLDATA 表:
- 为了避免连接数据库错误,确保 WebSphere Application Developer 中的测试服务器是停止的,第一次您需要创建一个新连接到本地 Derby 数据库。
- 在 ConcurrentAccQueryTables 项目中,切换到 Data 视图并打开 CreateSuplData.sql 文件。该文件包含在 BPEDB 中创建 SUPLDATA 表所需的所有 SQL 命令。
- 在编辑器中右键单击此文件,并选择菜单选项来运行 SQL。
- 验证 SQL 在 SQL Results View 中成功运行。
下一步是定义查询表。图 3 显示了一个应用程序所需要的查询表的高级视图,以及如何关联 BPEDB 数据库中的物理表或视图。
样例应用程序所需的查询表是基于 SUPLDATA 表中的访问补充数据和连接 TASK 和 WORKITEM 数据的,是为 Human Task Manager 预定义的。
查询表名 | 描述 |
---|---|
DW.SUPLDATA | 创建所有其他程序表定义时所需的补充表定义,以备参考。 |
DW.ASSIGNED | 任务分配给调用用户。 |
DW.CLAIM | 任务可由调用用户根据预定义的次序进行申明。 |
查询表定义已经创建了,在本文的 项目交换文件 中提供。首先创建一个补充查询表,供随后创建的复杂查询表引用。使用预定义 TASK 查询表(图 4)将连接定义在补充查询表中。
DW.ASSIGNED 查询表将被定义来返回 SUPLDATA 表中的所有列以及 TASK 表中的 TKIID 列。当任务被分配之后,授权级别仅限于个人。过滤器将定义在 Task 类型、State (Claimed)、Name 和 Namespace 字段来消除其他类型的任务返回。如果一个任务存在,数据将被放置在任务的 HTTP 会话中来完成后续步骤,如果只返回状态为已申明的任务,过滤器要被添加到查询表。
DW.ASSIGNED 查询表(图 5)需要检索分配给用户的任务,但是,如果有错误就不能完成。这个操作在新任务申明之前完成。这保证一次只有一个任务分配给用户。
DW.CLAIM 是最终查询表,返回一个任务作为潜在所有者工作项目的一部分,潜在所有者源自于 WORKITEM 视图中的 Group 工作项目行,与调用者 ID 相匹配。注意查询表必须是 TASK 查询表。授权仅限于 Groups,而且过滤器设置为 Task 类型、State (Ready)、Name 和 Namespace。
在此版 Integration Developer 中,查询表被部署到您工作空间的服务器中。切换到查询表视图并右键单击每个查询表,从 DW.SUPLDATA 查询表开始(因为它被后面的查询表引用),然后选择 Test on local WebSphere Process Server 菜单选项。输入管理员 ID 和密码,然后选择 Deploy 按钮。
通过验证控制台中的成功消息,确认 3 个查询表已经全部成功部署到服务器。操作完成之后,关闭查询表测试窗口。
业务整合模块包含任务模板(图 6),它是基于一个 To-do 任务创建的,有一个名称 “ConAccTask” 和一个名称空间 http://com.ibm.ca/htm。这是导入工作空间的项目交换文件其中一部分。
在这个例子中,Administrators 和 Potential Creators 将被设置为 cn=managers,o=defaultWIMFileBasedRealm 的 Group Id,这是标准 Integration Developer 安装的一部分。Potential Owners 被设置为一个运行时变量值,分配给任务的输入消息,供运行时变量 %htm:input.TaskRequest\GroupDn% 参考。
在此样例中所有组和用户所用的是 Integration Developer V7 默认安装。试用样例应用程序时,没有必要创建任何额外组或用户。
当您想运行并发任务测试时,动态 Web 应用程序中的 servlet 常用来以一种不复杂的方法执行测试、与 JMeter 交互。
servlet 将实现四个不同的方法,如表 2 所示,这些方法将根据 HTTP 请求中的 “action” 参数来执行。servlet 与 Human Task Manager 相互作用并保存必要任务数据,完成 HTTP 会话中的任何订阅请求。不再需要在活动之间传输 Task ID ,简化了 JMrter 测试。
方法 | 描述 |
---|---|
create | 创建一个任务并将它与预定义组联系在一起。 |
assignQueryTable | 分配任务给调用用户,并将 TKIID 放置在会话中,该方法将使用新的查询表方法进行申明 。 |
assignNosync | 分配任务给调用用户,并将 TKIID 放置在会话中,该方法将使用旧的查询方法,然后申明一个任务。此方法被用来阐述没有同步时会出现什么错误。 |
complete | 用存储在 HTTP 会话中的 TKIID 完成任务。 |
应用程序一个很重要的部分就是在部署描述符中定义的安全属性。这些设置需要传送安全证书给 Human Task Manager,将依次根据 Caller Principal(Subject 的一部分)确定任务的所有者或所有关系。图 7 展示了在 Web 项目中定义的安全角色和在应用程序中配置的绑定。设置指出 servlet 要求所有经过认证的用户要有一个用户名和密码 。
由于 JEE 5 规范的实施,使得安全性的定义不同于早期版本。早期定义安全角色的方法是使用 Web Application Project 中的 Security Editor。本例创建一个名为 “AllAuthRole” 的 Security Role,并将其与所有资源联系起来。
在应用程序的部署描述符中不再有一个 “聚集” 选项。这是通过部署描述符编辑器手工操作的。如果您需要创建一个新的应用程序,右键单击 EAR 项目并选择 Java EE > Generate WebSphere Bindings Deployment Descriptor,一个 ibm-application-bnd.xml 文件被创建,这样您就可以使用 “All Authenticated Users” 添加 Security Role。如图 8 所示。
带有对象 FilterOptions、AuthorizationOptions 和 Retry Count 的查询表 “DW.CLAIM” 被传递到方法(清单 1)。重试仅用于查询表执行时出现并发异常且查询表需要重新申明的情况下。当任务被创建且保存在补充数据中时,根据任务重要性定义一个 Sort Attribute,这是一个接收的参数。这将为您提供根据预定义次序声明任务的功能。ClaimResult 对象是申明请求的响应,包含任务 ID,TKIID,它现在分配给调用用户。
FilterOptions filter = new FilterOptions(); filter.setDistinctRows(true); filter.setSortAttributes("IMPORTANCE ASC"); AuthorizationOptions authorization = new AuthorizationOptions(); authorization.setGroupsUsed(true); int RETRY_COUNT = 5; List list = null; try { ClaimResult cr = lHtm.claim("DW.CLAIM", filter, authorization, list, RETRY_COUNT); if (cr != null and cr.getTKIID() != null) { tkiid = cr.getTKIID(); setTkiidInSession(request, tkiid); response = tkiid.toString(); } else { logger.info("No more tasks to claim, please create more!!!"); } } catch (Exception e) { e.printStackTrace(); response = "ERROR: " + e.getMessage(); } |
建议您更详细地查看 servlet,理解该测试所需的其他方法。
正如前面提到的,免费 Apache JMeter v2.3.4 负载测试应用程序 更适合在样例应用程序中测试并发性。
3 个独立的测试案例被创建,作为项目交换文件的一部分位于 JMeterTestCased 项目中。测试案例完成以下任务:
- 创建足够任务来运行后续并发测试。
- 查询之前创建的任务来分配和完成任务。这个测试案例使用两个用户来模拟查询表申明方法中的并发存取。
- 查询任务和前面的一样,但是现在调用异步方法来查询和申明任务。这个查询案例用来展示不使用首选方法时可能出现的错误。
- 将测试案例文件 ConcurrentAccTests.jmx 和 users.txt 文件从 JMeterTestCases 项目的测试案例目录下复制到 JMeter 安装位置的 testplans 目录下。
- 通过选择 JMeter 安装位置的 bin 目录下的 JMeter.bat 文件来启动 JMeter 应用程序。
- 从 File > Open 菜单打开之前复制的 ConcurrentAccTests.jmx 文件来查看 Navigation Area 中的 3 个 Thread Groups,如图 9 所示。
图 9. JMeter 桌面应用程序视图
- 如图 9 所示通过红色箭头,将所有 Thread Groups (Tests) 从 Tests 节点拖放到 Workbench 节点。改变端口号匹配您 WebSphere Process Server 测试环境的 HTTP 端口(默认是8080)。
您将要运行的第一个测试是创建一些任务来进行后续测试。
- 将 1-Create Tasks 从 Workbench 节点拖放到 Tests 节点。
- 扩展 1-Create Tasks 节点并在树中选择 Configure Creator User Element。测试案例使用 Integration Developer 中的标准用户来进行测试,但是这可以根据需要修改。您可以修改用户在配置元素中创建任务。
- 通过选择 Run > Clear All 菜单选择启动,运行任务之前重置所有报告数据,确保 Process Server Test 服务器正在运行,并确保可以在 Integration Developer 中查看控制台消息。
- 现在,选择 Run > Start 菜单选项。通过观察控制台中的输出可以看到测试正在运行,也可以看到 JMeter 窗口右上角的小盒子变绿(可能很快)。
- 测试完成后,如果控制台中没有报告错误,启动 Integration Developer 中的 Business Process Choreographer Explorer 来确保有 100 个新任务被创建。如图 10 所示。
图 10. 在 BPC Explorer 中查看任务数量
下一个将要运行的测试是调用该方法的 “2-Query Table Test”,它使用查询表进行申明。
- 将 1-Create Tasks 测试从 Tests 节点拖放到 Workbench 节点,并将 2-Query Table Test 测试从 WorkBench 节点拖放到 Tests 节点。
- 使用 CRTL-E 清理结果,并使用 CRTL-R 像之前那样运行测试。该测试案例使用 user.txt 文件作为用户输入文件,这将同时申明且完成 50 个任务。
- 切换回 BPC Explorer 并确认任务数量。现在您将看到的确有 50 个任务已完成。回到控制台,这应该没有错误报告。
为了建立对使用异步代码时所出现的错误的理解,运行 “3-Unsync Test”。
- 将 2-Query Table Test 从 Tests 节点拖放到 WorkBench 节点,并将 3-Unsync Test 移到 Tests 节点。该测试案例也使用 user.txt 文件作为用户输入,将同时申明且完成 50 个任务,如果一切顺利的话。两个用户同时循环进行两个活动。
- 测试结束时,您将在控制台中看到一些或者两个这种类型(清单 2 )的异常。
清单 2. 控制台中可能存在的异常
CWTKA0062E: Task instance state 'Claimed' of task '_TKI:a01b0127.e586669b. d6d5bef6.cd5e0000' does not allow the requested action 'claim()'. or CWTKA0024E: The '_TKI:a01b0127.e593764b.d6d5bef6.cd5e09ea' task does not exist.
这仅仅是一些可能的异常,但根据硬件和数据库,您可以使用该测试生成的大量异常。测试结束时,您可以在 BPC Explorer 中核实任务数量。尽管测试案例试图声明且完成全部 50 个剩余任务,但仍然有些任务没有完成。
本文着重介绍了 Human Task Manager 中使用查询表方法的新申明。用一个简单的样例应用程序证明该方法可在没有任何并发性异常的情况下使用 Apache JMeter 测试存取。样例应用程序决不能部署到产品系统中,只是展示了测试客户构建 Human Task Manager 应用程序所需的组件。查询表是一个有用的附加特性,已在 WebSphere Process Server 中使用,可以用于任何客户端应用程序。
原文链接:http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1006_vanzyl/1006_vanzyl.html