了解 EJB 调用如何在 WebSphere Application Server V6.1 中操作

许多应用程序使用部署在 IBM® WebSphere® Application Server 中的 EJB Enterprise JavaBeans™ (EJB)。与这些 EJB 组件通信需要使用到诸如 Internet ORB 间协议(Internet Inter-ORB Protocol,IIOP) 通信、JNDI 查找和工作负载管理等概念。此交互可能非常复杂,对许多 WebSphere 用户来说通常是个黑盒。本文提供有关 EJB 通信如何在 WebSphere Application Server 上下文中工作的基本知识。本文将讨论进出 ORB 的通信,以及对 EJB 容器中部署的 EJB 组件发出调用所涉及到的基本调用模式和组件的定义。本文假设读者对 J2EE™ 原理和 WebSphere Application Server 的一般管理知识具备基本的了解。 本文来自于 IBM WebSphere Developer Technical Journal

John Pape, WebSphere Application Server SWAT 团队, EMC

John Pape 目前供职于 WebSphere SWAT 团队,并致力于为利用 WebSphere Application Server、WebSphere Portal Server 和 WebSphere Extended Deployment 的客户提供危急情况 (crit-sit) 支持。此角色需要关注细节并保持“标新立异”的创新思维,并始终确保 IBM 客户获得尽可能最好的支持!


developerWorks 投稿作者

Dr. Mahesh Rathi, WebSphere Application Server SWAT 团队, IBM

Mahesh Rathi 博士自从 WebSphere Application Server 问世以来就一直从事 WebSphere Application Server 产品方面的工作。在加入 L2 Support 团队之前,他领导安全开发团队,并于 2005 年加入了 SWAT 团队。他全身心投入与苛刻的客户就热点问题进行的合作,并在压力环境中保持旺盛的精力。他从普渡大学获得了计算机科学博士学位,在加入 IBM 之前,他在威奇托州立大学从事软件工程教学。



2008 年 10 月 21 日

引言

对于许多 WebSphere 用户来说,EJB 通信就是一个黑盒。也就是说,我们了解调用方法“X”将从 EJB 业务逻辑返回所需的结果。在正常操作条件下,拥有此知识可能就足够了,因为通常不必要了解 ORB 的内部工作原理。然而,当性能问题或负载平衡问题出现时,有关 ORB 的深入知识可以极大地增强问题确定工作,并减少问题解决时间。与任何 WebSphere 组件一样,如果了解 ORB 的操作机制及其相关通信协议,在进行故障排除时可以获得进一步的专业知识。


ORB

您可以点击如下链接,马上下载 WebSphere Application Server 软件 V7 版本,体验其为您带来的新特性及新功能。

更多关于 WebSphere Application Server 的技术资源,请参考:

ORB 是 CORBA 或公共对象请求代理体系结构 (Common Object Request Broker Architecture) 的核心组成部分,在面向对象的分布式应用程序中,它旨在使得远程对象像本地对象一样可用。此外,ORB 允许这些对象彼此通信,而不管用于实现那些对象的特定平台、技术和语言是什么。

CORBA 是由对象管理组织 (Object Management Group,OMG) 创建的一种开放、与供应商无关的分布式计算规范,该组织是由 600 多家软件供应商和促进开放标准接口的其他公司组成的联盟。CORBA 及其接口定义语言(Interface Definition Language,IDL)提供了一种用于表示对象的公共格式,使用该格式表示的对象可分布到采用 Java™、C、C++ 和其他语言编写并运行在不同操作系统和计算机上的应用程序。

ORB(对象请求代理)在应用程序服务器运行时中起作不可或缺的作用。ORB 实现为 Java 虚拟机(Java Virtual Machine,JVM)的一部分。IBM WebSphere Application Server 包括了管理 ORB 实例的附加代码(一般称为扩展 ORB),同时还提供了用于对象服务(例如安全性)的插件框架。这个 IBM ORB 实现与 Sun™ ORB 不同;代码库完全不同。它是 EJB 容器赖以进行代理通信的基础,以便实现 Java 远程方法调用(Java Remote Method Invocation,RMI)交互。RMI 是 Java 执行远程通信的传统方法,并使用名为 Java 远程方法协议(Java Remote Method Protocol,JRMP)的非标准化协议在 Java 对象之间通信。在最基本的级别上,RMI 只是 Java 的远程过程调用(Remote Procedure Call,RPC)的面向对象版本。WebSphere Application Server 使用 ORB 促进客户端/服务器 RMI 通信,以及进行组件之间的通信。

ORB 管理针对远程 Java 对象(例如 EJB 组件)的入站和出站请求。ORB 为客户端提供了一个定位服务器上的 EJB 和像调用本地操作一样调用那些 EJB 上的操作的框架。(此概念称为本地-远程透明性。)ORB 与 EJB 容器之间的关系可使用图 1 进行描述。

图 1. ORB 和 EJB 容器
图 1. ORB 和 EJB 容器

ORB 间通信

ORB 之间的通信是通过 IIOP 完成的,后者是 General Inter-Orb Protocol (GIOP) 抽象参考规范的具体实现。可互操作的对象引用(Interoperable Object Reference,IOR)只不过是 CORBA 或 RMI-IIOP 对象引用的字符串表示形式,其格式为 ORB 能够理解的格式。您可以将 IOR 视为日常代码编写工作中使用的普通 Java 对象引用。IIOP 将 GIOP 映射到 TCP/IP 通信堆栈。

GIOP 协议指定了几种不同类型的消息,例如请求消息、应答消息、定位请求消息、定位应答消息和片段消息。请求和应答消息类型是不言而喻的,因为它们处理客户端和服务器应用程序之间的请求和响应交互。除非您曾经必须通读 GIOP 跟踪以解决某个问题,否则您可能不那么熟悉定位请求和片段消息类型。

  • 定位请求消息类型用于验证 ORB 理解并存放所请求的远程对象。如果 ORB 不知道定位请求消息中请求的对象,它将尝试提供有关客户端可以在何处找到所请求对象的详细信息(例如 OBJECT_FORWARD,它指向确实存放有该对象的服务器)。
  • 片段消息是先前传送到 ORB 的消息的延续。

处理大型 GIOP 消息可能会给 ORB 带来问题。可以将 GIOP 消息分割为可管理的各个部分,以简化和加速处理。可以在 WebSphere Application Server 中设置自定义属性,指定用于分割消息的确切大小(或者是否根本有必要分割消息)。缺省情况下,WebSphere Application Server 将 GIOP 消息分割为 1024 字节大小的片段。

在最基本的交互场景中,客户端和服务器 ORB 直接彼此通信,以满足应用程序对远程资源的请求。然而,在较复杂的交互中,例如带工作负载管理功能的集群服务器,除客户端和服务器以外的其他处理器可能参与(对本文来说)NodeAgent 进程。

每个应用程序服务器包含一个侦听传入请求的 ORB。该 ORB 具有三个或更多个与之关联的端口:ORB 侦听器端口、引导端口和安全端口。如果未启用 ORB 安全性,ORB 侦听器端口是 ORB 侦听传入 IIOP 请求的实际端口。引导端口始终是得到良好广告的活动端口,并且始终返回间接 IOR,其中包含安全和不安全的侦听器端口。良好构造的客户端应该始终引导至远程资源所驻留的服务器(或者如果资源驻留在集群中,则引导至指向该集群的多主机提供者 URL)。还有另外三个与 ORB 和安全性关联的端口:CSIv2 客户端身份验证 SSL 端口、CSIv2 SSL 端口和 SAS SSL 端口。(这些端口的详细信息超出了本文的范围,这里就不进行介绍了。)缺省情况下,ORB 侦听器端口是在运行时从平台的临时端口范围中动态地确定的。然而,由于各种原因,可以将这些端口设置为特定的静态端口,例如由于防火墙规则、业务策略等等。

当 ORB 客户端请求对某个远程对象的引用时,远程 ORB 将使用一个可互操作的远程对象引用 (IOR) 进行应答,IOR 不过是 CORBA 或 RMI-IIOP 对象引用的字符串表示形式,其格式为 ORB 能够理解的格式,并且在非常基本的级别上,包含了可在其上找到该对象的服务器的主机和端口信息。可以将 IOR 视为在日常代码编写工作中使用的典型 Java 对象引用。


NodeAgent 是如何参与的?

首先,NodeAgent 进程仅参与 WebSphere Application Server Network Deployment 产品中的 ORB 事务;它在基本应用程序服务器解决方案中不存在。NodeAgent 进程包含一个称为位置服务守护进程的服务,该服务通过为守护进程提供指向上述应用程序服务器的直接 IOR,从而使应用程序能够注册它们的服务和远程对象。以后,当定位请求进入位置服务守护进程时,它将使用该注册信息向客户端返回一个直接 IOR,该 IOR 指向所注册的应用程序服务器的 ORB 侦听器端口。可以将该注册/IOR 信息视为某种类型的路由表,守护进程使用它来定位 EJB 和位于特定 NodeAgent 所管理的各个应用程序服务器上的其他资源。

在所管理的应用程序能够启动之前,NodeAgent 必须在该节点上本地可用。可以对应用程序服务器进行配置,以便消除对 NodeAgent 进程(实际上是位置服务守护进程服务)的依赖性。然而,此设置涉及到执行 IIOP 请求的静态路由,从而使得 WebSphere Application Server 的工作负载管理服务变得无效。除非确实需要,否则应该避免这种静态路由设置。(在自己做出此评估结果之前,请咨询 IBM Support。)

在部署 EJB 的相同节点上,在应用程序服务器操作过程中,如果 NodeAgent 进程无响应或者必须关闭或重新启动,一旦 NodeAgent 不可用,可能会在服务器日志中引发异常。出现这些异常消息的原因在于,一旦从进程中删除 NodeAgent,IIOP 通信就会以阻止 ORB(客户端和服务器)正确通信的方式被改变。然而,只要客户端已经有指向所需服务器的直接 IOR,已经创建了 EJBHome 对象,并且正在对该 EJB 发出远程调用,则 NodeAgent 不大可能参与随后的 IIOP 通信。

在理想的情况下,在特定节点上的所有应用程序服务器完成向 NodeAgent 上的位置服务守护进程的注册之前,发送到位置服务守护进程的针对与 EJB 相关的对象的传入定位请求不会进入。当针对服务器上还未注册或临时关闭(因而不再注册)的对象的定位请求进入时,将向客户端返回一个 CORBA.OBJECT_NOT_EXIST 异常。在此情况下,需要检查应用程序服务器的状态,以确保它们全都已启动和运行,并且已向位置服务守护进程注册。


理解 ORB 调用模式

为了使高级应用程序功能(例如 EJB 组件)正常工作,必须进行 ORB 间通信。我们可以观察到两种基本的场景:

  • 独立应用程序服务器(WebSphere Application Server,不是 Network Deployment)
  • WebSphere Application Server Network Deployment 环境中的集群应用程序服务器。

下面几个部分将描述这些场景。

WebSphere Application Server 基本实例

在此场景中,EJB 组件及其客户端包含在单独的应用程序服务器中。用于发出调用的客户端代码类似如下:

清单 1
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming
.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL,"corbaloc::isador:2810");
Context ctx = new InitialContext(env);
TestEJBHome home = (TestEJBHome)
PortableRemoteObject.narrow(ctx.lookup("ejb/ejbs/TestEJBHome"),
	TestEJBHome.class);
TestEJB bean = home.create();

粗体文本显示的代码是导致 ORB 调用的代码行。在实际操作中,您可以按照图 2 中的事件跟踪调用过程,图中按自顶向下的顺序列出了事件。

图 2. 基本实例中的 ORB 事件调用
图 2. 基本实例中的 ORB 事件调用

图 2 划分为三个部分,每个部分对应于清单 1 中的 Java 代码的一个部分:

  • 上方部分包含在客户端上创建 InitialContext 时产生的事件。
  • 中间部分包含 InitialContext.lookup() 方法中产生的事件。
  • 下方部分包含在创建 EJB 实例时产生的事件。

在此关系图中,您可以看到从服务器获得初始上下文的过程涉及到向 ORB 引导端口上的 ORB(这里的客户端和服务器 ORB 是同一个 ORB)发送定位请求消息。最终的应答消息包含一个直接 IOR(带有主机以及 TCP/IP 和 SSL 端口信息),该 IOR 将客户端指向包含所请求对象的服务器。接下来,客户端发出另一个定位请求消息,但这次是发送到 ORB 的侦听器端口。然后,客户端从 ORB 请求某些信息以建立初始上下文。

在获得 InitialContext 值以后,然后客户端代码在 JNDI 命名空间中执行查找,以确定如何获取对所需远程对象 (WLMTestEJB) 的引用。为了完成此任务,客户端又发出另一个针对 ORB 的侦听器端口的定位请求。ORB 通过定位应答消息回应客户端,指出该对象确实包含在本地。为了响应该定位应答,客户端然后请求 ORB 解析该对象并向客户端返回引用。在幕后,这要求 ORB 使用联系类 (tie class) 连接到实际 Java 对象(其中带有到达 ORB 的请求)。当客户端获得引用时,它使用“窄”调用将从 ORB 返回的通用对象处理成所需的对象类型。

该代码所做的最后一件事情是创建远程 EJB 的实例。为了完成此过程,客户端向远程 ORB 发出定位请求,ORB 使用一个表明该对象存在的定位应答来应答该请求。最后,客户端调用远程对象上的 create() 方法。当该过程在 ORB 中完成时,ORB 对响应进行封送处理并返回给客户端。进出 ORB 的所有数据(例如方法参数和方法返回值)都使用称为公共数据表示形式(common data representation,CDR)的格式进行序列化和反序列化。因而,传入 ORB 的所有值都必须实现可序列化的接口。

此基本应用程序服务器场景中使用的定位请求消息是由 ORB 自己进行处理的简单定位请求。这与下一个场景不同,因为位置服务守护进程插件(附加到 ORB 实例)将处理与定位请求相对应的消息。

WebSphere Application Server Network Deployment 集群实例

在此场景中,主要区别在于客户端 ORB 和服务器 ORB 几乎始终是两个不同的 JVM 实例,并且通常位于完全单独的主机上。该过程似乎大致相同,但是您将注意到包含在 NodeAgent 中的位置服务守护进程服务器的参与。清单 2 显示了发出调用所涉及到的代码。

清单 2
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming
.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL,"corbaloc::boris:9811,:natasha
:9812");
Context ctx = new InitialContext(env);
TestEJBHome home = (TestEJBHome)
PortableRemoteObject.narrow(ctx.lookup("ejb/ejbs/TestEJBHome"),
	TestEJBHome.class);
TestEJB bean = home.create();

相对于前一个示例,此代码仅在一个地方进行了更改:放在环境 Hashtable 对象的 PROVIDER_URL 键中的值。在此例中,开发人员包括了多个 corbaloc URL,其中每个 URL 指向一个单独服务器的引导端口。此更改向该过程引入了一些容错和故障转移功能,因为该代码现在具有两条可获得 InitialContext 对象的路径。与在前一个场景中一样,粗体文本显示的代码负责生成远程 ORB 请求。图 3 演示了此场景的事件序列,其格式设置与前一个示例相同。

图 3. 集群实例中的 ORB 事件调用
图 3. 集群实例中的 ORB 事件调用

对于上方部分的 InitialContext 对象创建,此场景与前一个场景之间不存在明显的区别。然而,随着 WebSphere Application Server 工作负载的添加,存在一些细微的区别。

首先,在 InitialContext 的创建过程中(上方部分),将会准备一个指向该单元的每个位置服务守护进程集群的 IOR 列表,并在对话的 getProperties() 部分期间返回给客户端 ORB。当客户端 ORB 对服务器 ORB 发出进一步的调用时,客户端的工作负载管理插件遍历该列表并发出 resolve_complete_info 请求。第一个请求被路由到 NodeAgent 中的位置服务守护进程服务(显示为中间部分的第一个调用),所需的集群数据在那里以指向目标服务器的直接 IOR 的形式发回给客户端。

在该关系图的下方部分,您可以看到第一个场景中发出的定位请求消息并不需要,而是立即调用了 create() 方法,而不必处理附加的定位请求,因为工作负载管理已经对适当的应用程序服务器进行了“定位”。


总结

本文定义了 ORB,以及它如何为应用程序服务器运行时提供至关重要的功能,以满足对 EJB 服务器发出远程请求的客户端的需要。本文还解释了构成 ORB 间通信的高级事件序列,以及 NodeAgent 在客户端与服务器之间的 ORB 通信部分中所起的作用。

有关这些主题的信息还有很多。如果希望继续进行阅读,您可能希望浏览以下主题:

  • GIOP 协议
  • ORB/EJB 容器的问题确定
  • RMI over IIOP
  • Java Naming and Directory Interface (JNDI)
  • EJB 集群
  • WebSphere 工作负载管理(WebSphere workload management,WLM)
  • CORBA 和 OMG。

致谢

作者感谢 Paul Bullis 和 Claudia Barrett 对本文中讨论的主题提供了相关指导和说明。

参考资料

条评论

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, SOA and web services
ArticleID=343530
ArticleTitle=了解 EJB 调用如何在 WebSphere Application Server V6.1 中操作
publish-date=10212008