|
摘要 在企业中,许多计算机由于在其上执行工作的性质而未得到充分利用,或者因为过了上班时间而干脆得不到使用。在许多情况下,应用服务器耗光了宝贵的CPU(尤其是在执行CPU密集型的数学运算时),而网络上的其他计算机则闲置一旁。本文提出了一种框架,用于把Java消息服务(Java Messaging Service,JMS)客户端放置在这些未充分利用的计算机上,以分担一些通常应由服务器执行的工作。该客户端可以监听某个要执行的工作单元的请求队列,然后在应答队列中做出响应。此外,本文还给出了一个BEA Weblogic Integration 8.1架构的例子,它通过把一个工作流以及相关的Java控件用作替代框架,把工作分发到远程客户端上,从而把工作单元可靠地分发给JMS请求队列。
简介 本文提出了一种J2EE框架,用于解决把工作分配给未充分利用的计算机资源这个难题。具体来说,可以把JMS客户端放置在这些未充分利用的计算机上,从而分担一些通常应由服务器执行的工作。该客户端可以监听某个要执行的工作单元的请求队列,然后在应答队列上做出响应。可以使用一组消息驱动bean获取应答队列上的响应消息,以便进行进一步的处理。此外,还可以使用一种servlet实现来管理性地启动用于创建(要发送给JMS客户端的)工作单元的整个子流程,并使用它来终止这个子流程。
我使用常见的BEA WebLogic Server作为把离散的工作单元分配给分布式JMS客户端的例子。在另一个更为复杂的例子中,BEA Weblogic Integration (WLI)工作流也执行类似的分发任务,但是通过对请求队列进行监控,它在灵活性、Java控件的可重用性和可伸缩性等方面要更好一些。
使用的例子 业内有相当多的例子可以演示如何使用JMS框架来充分利用计算机进行并行处理。例如:
一个银行应用程序可以实现抵押贷款,并以不同的比率和年份执行几类利息计算,从而为信贷官员提供与每个申请者相关的、可能影响借贷类型的数据。所有不同种类的计算可以按照申请者分配给可用的计算机来执行,然后把结果返回给应用服务器储存起来。 一个记帐系统可以从数据库读取记录,然后重新计算记录中的数字,以求做到更加精确。对于每条记录,它可能需要连接到业务用户的本地系统中以获得辅助数据,这可能需要几秒钟。如果顺序执行,当涉及到的记录上千时,这种方法不仅很慢,而且可能进一步延长服务器线程等待从各地返回响应的时间。通过把这些工作分发给JMS客户端,不仅可以并行完成处理,而且还可以节省服务器线程。 一个天气预报系统或线性优化系统可能需要操纵或执行矩阵乘法。随着矩阵的大小和数量逐步增加,服务器CPU的负担也随之加重。如果这种情况经常发生,那么通过把矩阵操作和乘法分发给其他计算机上的JMS客户端,服务器的CPU就可以节省下来用于其他工作。 使用常规的Weblogic Server来分发工作单元 借鉴最后一个例子,我将构建一个简单的例子,用于执行矩阵乘法,同时说明如何使用JMS框架把计算工作分发给企业中的计算机资源。JMS客户端将收到一个工作单元实例,之后,它将会调用其doWork()方法。在这个简单的例子中,doWork()方法将把2个3×3的矩阵相乘,然后把结果保存到一个结果矩阵中。 接着,JMS客户端使用工作单元实例的一个副本(工作是在这上面执行的)对应答队列做出响应。一个消息驱动bean将接受已完成的工作。图1说明了我将要讨论的各个组件:

图 1.该Weblogic Server实现中的各个组件
这种方法以常规方式使用了JMS系统。在下面的内容中,我将引入一些代码,并考虑几个扩展问题。
工作单元类 JMS请求队列上的每个类都将实现一个UnitOfWork接口,该接口有一个特别有趣的方法,叫做doWork():
public interface UnitOfWork extends java.io.Serializable { // This method executes itself on the client machine public void doWork(); // This method prints the current contents of performed work public void print(); // This method stores the instance into a backing store public void store(); }
在我们这个简洁而直观的例子中,我使用一个SimpleMatri类实现了UnitOfWork接口:
public class SimpleMatrix implements UnitOfWork { private Integer m1[][]; private Integer m2[][]; private Integer result[][]; private Integer rows = new Integer(3); private Integer cols = new Integer(3); // May initialize m1 and m2 by locating records from a database public SimpleMatrix() { } // This method actually multiplies m1 x m2 and stores in result public void doWork() { } // This method stores result into a backing store public void store() { } // This method prints the current contents of result public void print() { } }
[1] [2] [3] [4] [5] 下一页
|