站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题通过Message-Driven beans来添加并发处理(一)

通过Message-Driven beans来添加并发处理(一)

摘要: 通过Message-Driven beans来添加并发处理(一)
内容: 概要:
在使用J2EE框架的应用程序中添加并发处理往往受到一些严格的限制,主要原因有两个:首先EJB的规范限制了在EJB容器中产生新的用户线程, 另外, SessionBean的方法是必须被同步调用的. 但是, 为了保证响应时间,相当多的应用程序必须实现并发处理. 有几种方法可以克服这种上述的限制,其中消息驱动由于其于生俱来的异步处理能力, 以及通过JMS和Message-Driven beans可以与J2EE应用服务器紧密的结合,成为了其中最突出的解决方法. 本文章详细描述了如何使用MDBS来为J2EE应用程序实现并发处理.


并发程序能够同时处理多个任务. 并发改善了程序的数据读写吞吐量, 执行速度以及响应速度. 在单处理器系统中, 并发程序通过利用重叠IO读写时间来有效的利用了计算机的资源. 在多处理器系统中, 并发程序通过在多个CPU上并发执行程序来最大限度的提高吞吐量.

有若干方法可以实现并发. 在Java中, 可以通过多线程来实现. 相对于独立的进程, 线程具有较低的系统开销. Java对线程提供内在的语言级别的支持, 所以, 并发程序的支持是Java不可缺少和引人注意的一个特点.

在现实中,我们会发现并发能力对很多应用都是都不可缺少的. 本文要描述的例子是如何在多个零售处搜索某个商品的最低价格及供货信息. 本文描述了在J2EE架构下的几种不同的实现,以及在单用户请求下,如何使用MDBS来实现并行处理. 我们称该应用为Price Buster.

为了证明为什么Price Buster需要并发处理, 我们先来讨论这个应用是做什么的,需要哪些功能, 以及在J2EE架构下最好的实现方法. 我们的应用通过Web层接受用户输入的货物名称或型号来作为搜索条件, 然后调用后台的程序来搜索多个供货数据源该货物的价格和供应情况, 格式化结果,最后返回给查询者.
本应用的理想实现是在尽可能短时间内, 搜索尽量多的供货数据源. 连接多个供货数据源进行查询的后台进程, 占消耗时间最大一部分.假设在一个数据源查询某个货物的价格需要15秒, 那么, 如果查询操作是一个接一个的串行进行, 查询10个数据源至少 需要150秒.对于客户来说, 150秒的响应时间显然是不可接受的. 在对多个数据源进行查询的前提下, 为了保证响应时间, 查询操作必须并行执行不是串行.

现在让我们来讨论, 在使用J2EE架构下的几种不同的实现方法. 最典型和通用的方法是由Web模块和EJB模块组成. Web模块由servlets和jsp实现, 负责处理客户会话和数据显示, EJB模块负责连接供货源进行查询.整体架构如图一所示. EJB查询模块一个接着一个的从三个供货源A,B和C获得货物的价格, 最重要的一点是查询操作是串行执行的, 所以将结果显示给客户至少需要45秒.


IMG http://www.javaworld.com/javaworld/jw-07-2003/images/jw-0718-mdb1.gif[/IMG]
图一

在这个实现里, 用户的响应时间依赖于供货数据源的数量和查询一个数据源所需要的时间. 尽管这个实现提供了正确的功能, 但是有个严重的设计缺点, 响应时间随着供货源数量的增加而线性增加, 因此查询20个供货源至少需要300秒, 这显然是不可接受的.

为了正确实现功能并且达到理想的响应时间, 本应用必须重新设计, 使用另外的技术使查询操作是并行进行而不是串行. 换句话说, 我们需要在上面的实现中实现并行操作来获得更快的响应时间. 如之前所述, 在JAVA程序中, 这个可以通过多线程来实现, 例如为多个线程分配单独的任务. 这种技术在所分派的任务是重于IO读写而不是重于CPU计算的时候特别有效, 正如Price Buster程序. 供货源的EJB组件连接数据库进行IO读写, 至少需要15秒的时间, 在这个时间内, EJB组件只等待结果, 而不作任何操作, 因此, 这个程序是最适合使用多线程实现的.

下面是几种支持并发的方法:
1. 修改Web模块的实现, 在Servlet中使用多线程. 每个工作线程可以直接调用EJB组件, 每个工作线程负责对一个供货数据源的查询. 当有请求到来时, Servlets根据当前数据源的数量, 生成若干工作线程, 每个线程调用EJB组件进行查询. 这时Servlet主线程可以等待查询结果或者进行超时处理.这种方法固然解决了问题, 但是它违背了J2EE基本的设计原则, 就是应用开发人员应该专注于应用逻辑的处理, 而不应该关心多线程和同步处理等系统级的问题.

2. Search EJB组件可以生成多个线程来并行的调用Retailer EJB组件.不幸的是,这种方法是完全不可取的. 因为EJB的规范限制在容器里创建新的用户线程. 注意EJB容器本身就是实现并发处理, 支持多客户连接的.这个限制的主要原因是, J2EE技术本身就是提供一个实现强伸缩性的服务器端组件的架构, 是由它来提供并发处理及其他服务的. 这个架构减轻了开发人员实现复杂多线程程序的难度, 容器通过创建线程更能有效的管理资源的分配.

3. 利用MDBs来实现Retailer EJB组件. Search EJB组件可以同时发若干个任务消息给若干Retailer组件, 每个接收到消息的Retailer组件处理任务, 从而实现并发处理. Session Bean不能这么实现是因为它们必须是同步并且线性的被调用的. 换句话说, 因为MDBs可以根据消息事件异步的被调用, 因此可以并行的处理请求.

我们要清楚EJB规范的限制. 最佳的实现方法是第三个:异步的调用MDBs. 在不同的系统组件之间进行异步通信, 消息是最通用和可靠的机制. 通过JMS和MDBs技术, 消息处理已经非常紧密的集合在J2EE框架中.本文剩余的内容将说明如何通过MDBs,在EJB中支持并行处理.

现在我来讨论如何通过MDBs为Price Buster支持并发处理的细节问题. 要使用MDBs, 首先要使用支持EJB2.0规范的应用服务器, 其次要采用支持JMS接口的消息软件,例如IMB的MQ套件. 最好是选择能够和应用服务器很好集成的,例如WebSphere+MQ就是一个不错的选择.

关于翻译作者:
wqx,职业程序员,喜欢健身,爬山,现居广州。可以通过wqx_dev@263.net与他联系,或者点击http://www.matrix.org.cn/user_view.asp?username=wqx查看他的信息
Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd, scwcd 概要
↑返回目录
前一篇: 通过Message-Driven beans来添加并发处理(二)
后一篇: 切入商业应用(一)