Context.PROVIDER_URL 逗号间隔

来源:互联网 发布:mysql error 2002 编辑:程序博客网 时间:2024/04/27 16:22

 http://blog.csdn.net/wonder4/article/details/1662313

 

WebLogic JNDI

下列部分介绍如何使用 WebLogic JNDI 编程:

  • 使用 WebLogic JNDI 将 Java 客户端连接到单个服务器
  • 设置 InitialContext 的 JNDI 环境属性
  • 使用上下文查找已命名对象
  • 使用已命名对象获取对象引用
  • 关闭上下文
  • 使用群集环境中的 WebLogic JNDI
  • 使用 J2EE 组件的 JNDI
  • 设置外部 JNDI

 


使用 WebLogic JNDI 将 Java 客户端连接到单个服务器

WebLogic Server JNDI 服务提供程序接口(Service Provider Interface,简称 SPI)提供一个允许远程 Java 客户端连接到 WebLogic Server 的InitialContext 实现。客户端可以指定标识特定 WebLogic Server 部署的标准 JNDI 环境属性,以及用于登录 WebLogic Server 的相关连接属性。

要与 WebLogic Server 交互,Java 客户端必须能够获取某个远程对象的对象引用,并能够调用对该对象的操作。要完成此操作,客户端应用程序代码必须执行下列步骤:

  1. 设置 InitialContext的 JNDI 环境属性。
  2. 使用 WebLogic Server 建立 InitialContext
  3. 使用上下文查找 WebLogic Server 名称空间中的已命名对象。
  4. 使用已命名对象来获取远程对象的引用,并调用对远程对象的操作。
  5. 关闭上下文。

下列部分讨论连接到特定 WebLogic Server 的 JNDI 客户端操作。有关在 WebLogic Server 群集中使用 JNDI 的详细信息,请参阅在群集环境中使用客户端的 WebLogic JNDI

必须将 WebLogic Server 环境的对象下载到 WebLogic Server JNDI 树中,才能使用 JNDI 访问该对象。

注意:下列操作不受支持,而且在启动时会导致出现故障:绑定使用 WebLogic Server 6.1 类生成的对象,以及将其部署到 WebLogic Server 7.0 或更高版本。

 


设置 InitialContext的 JNDI 环境属性

任何 Java 客户端应用程序必须执行的第一项任务是创建环境属性。InitialContext 工厂使用多种属性自定义特定环境的InitialContext。可以使用散列表或 WebLogic 环境对象的 set() 方法来设置这些属性。这些指定为名值对形式的属性确定 WLInitialContextFactory 如何创建上下文。

下列属性用于自定义 InitialContext

  • Context.PROVIDER_URL- 指定提供命名服务的 WebLogic Server 的 URL。默认为t3://localhost:7001
  • Context.SECURITY_PRINCIPAL- 指定用于身份验证的用户(即在 WebLogic Server 安全领域中所定义的用户)标识。该属性默认为guest 用户,除非线程已与 WebLogic Server 用户关联。有关详细信息,请参阅将 WebLogic 用户与安全上下文关联
  • Context.SECURITY_CREDENTIALS - 指定Context.SECURITY_PRINCIPAL 属性中定义的用户密码,或指定使用已定义的 Context.SECURITY_CREDENTIALS 属性来实现 weblogic.security.acl.UserInfo 接口的对象。如果在此属性中传递 UserInfo 对象,则忽略Context.PROVIDER_URL 属性。该属性默认为 guest 用户,除非线程已与某个用户关联。有关详细信息,请参阅将 WebLogic 用户与安全上下文关联

可以在客户端或服务器使用相同属性。如果在服务器端对象定义属性,则使用本地上下文。如果在客户端或另一台 WebLogic Server 上定义属性,则上下文委托在Context.PROVIDER_URL 属性所指定的 WebLogic Server 上运行的远程上下文。绑定到服务器的远程对象不能接受 peerGone 提供的服务,且在客户端失败时不可访问。

创建上下文后,有些属性就不可再更改。这些属性包括提供程序 url、用户凭据和工厂。创建上下文后,AddToEnvironment 可用于更改其他属性。

清单 3-1 说明如何使用Context.INITIAL_CONTEXT_FACTORY 属性和 Context.PROVIDER_URL 属性获取上下文。

清单 3-1 获取上下文
 Context ctx = null;Hashtable ht = new Hashtable();ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");ht.put(Context.PROVIDER_URL,"t3://localhost:7001");try {ctx = new InitialContext(ht);// 使用程序中的上下文}catch (NamingException e) {// 发生故障}finally {try {ctx.close();}catch (Exception e) {// 发生故障}} 

其他 WebLogic 特定的属性也可以用于控制如何将对象绑定到群集范围的 JNDI 树。是否跨群集中每个服务器的 JNDI 树复制绑定,取决于设置这些属性的方法。诸如这些属性由weblogic.jndi.WLContext 类的常量来标识。有关 JNDI 相关的群集问题的详细信息,请参阅在群集环境中使用客户端的 WebLogic JNDI

使用散列表创建上下文

可以使用指定设置 InitialContext 的 JNDI 环境属性中所述属性的散列表创建上下文。

为此,将散列表传递到 InitialContext 的构造方法。属性 java.naming.factory.initial 用于指定如何创建InitialContext。要使用 WebLogic JNDI,必须始终将 java.naming.factory.initial 属性设置为 weblogic.jndi.WLInitialContextFactory。此设置标识了实际创建上下文的工厂。

使用 WebLogic 环境对象创建上下文

也可以使用 weblogic.jndi.environment 实现的 WebLogic 环境对象创建上下文。虽然环境对象是 WebLogic 特定的,但它具有下列优势:

  • 具有一组默认设置,可以减少需要编写的代码量。
  • 简便的 set() 方法可以提供编译时类型安全。类型安全set() 方法可以节省编写和调试代码的时间。

WebLogic 环境对象提供下列默认设置:

  • 如果未指定 InitialContext 工厂,则默认使用WLInitialContextFactory
  • 如果未在 Context.SECURITY_PRINCIPALContext.CREDENTIALS 属性中指定用户和密码,则默认使用 guest 用户和密码,除非线程已与某个用户关联。
  • 如果未指定 Context.PROVIDER_URL 属性,则默认使用t3://localhost:7001

如果希望用这些默认设置创建 InitialContext,请编写下列代码:

 Environment env = new Environment();Context ctx = env.getInitialContext();

如果希望只将 WebLogic Server 设置为用于访问客户端群集的分布式命名服务(Distributed Name Service,简称 DNS),请编写下列代码:

 Environment env = new Environment();env.setProviderURL("t3://myweblogiccluster.com:7001");Context ctx = env.getInitialContext();
注意:每次新建 JNDI 环境对象的同时,也在创建新的安全范围。使用 context.close() 方法结束该安全范围。注意:如果使用 IIOP 协议,则 environment.getInitialContext() 方法不能正常工作。

清单 3-2 演示了使用 JNDI 环境对象创建安全上下文。

清单 3-2 使用 JNDI 环境对象创建安全上下文
weblogic.jndi.Environment environment = new weblogic.jndi.Environment();environment.setInitialContextFactory(weblogic.jndi.Environment.DEFAULT_INITIAL_CONTEXT_FACTORY);environment.setProviderURL("t3://bross:4441");environment.setSecurityPrincipal("guest");environment.setSecurityCrendentials("guest");InitialContext ctx = environment.getInitialContext();

从服务器端对象创建上下文

也可能需要从在 WebLogic Server 的 Java 虚拟机(Java Virtual Machine,简称 JVM)上实例化的对象(Enterprise JavaBean (EJB) 或远程方法调用(Remote Method Invocation,简称 RMI)对象)创建上下文。使用服务器端对象时,不需要指定Context.PROVIDER_URL 属性。只有要以特定用户登录时,才需要用户名和密码。

要从服务器端对象创建上下文,首先必须新建一个 InitialContext,如下所示:

 Context ctx = new InitialContext();

不需要指定工厂或提供程序 URL。默认情况下,上下文创建为 Context 并连接到本地命名服务。

将 WebLogic 用户与安全上下文关联

请参阅 JNDI 上下文和线程。

JNDI 上下文和线程

创建具有用户名和密码的 JNDI 上下文时,即将用户和线程关联起来。创建上下文后,用户被上推到与线程关联的上下文堆栈。在启动线程上新的上下文之前,必须关闭第一个上下文,以使第一个用户不再与线程关联。否则,每次新上下文创建后,用户都会被下推到堆栈。这不仅不能高效使用资源,还可能导致ctx.lookup() 调用返回错误的用户。下列步骤演示了上述情况:

  1. user1 创建一个名为 ctx1 的上下文(具有用户名和凭据)。在创建上下文的过程中,user1 与线程关联,并被上推到与线程关联的堆栈。现在当前用户是user1
  2. user2 创建另一个名为 ctx2 的上下文(具有用户名和凭据)。此时,线程使某个用户的堆栈与之关联。User2 位于堆栈顶部,而user1 位于其后,因此 user2 作为当前用户使用。
  3. 如果调用 ctx1.lookup("abc"),则作为标识使用的是user2,而不是 user1,因为 user2 位于堆栈顶部。要获得预期结果,即调用 ctx1.lookup("abc") 作为 user1,则需要调用 ctx2.close() ctx2.close() 调用会从与线程关联的堆栈中删除user2,这样,现在 ctx1.lookup("abc") 调用可以按预期使用user1注意:当启用 weblogic.jndi.enableDefaultUser 标志时,会有两种情况因为 close() 调用并未从堆栈中删除当前用户而导致出现 JNDI 上下文问题。有关如何避免出现 JNDI 上下文问题的详细信息,请参阅如何避免潜在的 JNDI 上下文问题。

如何避免潜在的 JNDI 上下文问题

通常是调用 close(),如JNDI 上下文和线程中所述。不过,在启用 weblogic.jndi.enableDefaultUser 标志后,也会发生非预期行为,如下面的异常:

上次使用

使用 IIOP 时,当有一个上下文位于堆栈中,而由 close() 来删除该上下文,会发生非预期行为的异常。从堆栈中删除的上一个上下文标识确定当前用户的标识。下列步骤介绍了上述情况:

  1. user1 创建一个名为 ctx1 的上下文(具有用户名和凭据)。在创建上下文的过程中,user1 与线程关联且存储在堆栈中,即将当前标识设置为user1
  2. 调用 ctx1.close()
  3. 调用 ctx1.lookup()。当前标识是 user1。
  4. user2 创建一个名为 ctx2 的上下文(具有用户名和凭据)。在创建上下文的过程中,user2 与线程关联且存储在堆栈中,即将当前标识设置为user2
  5. 调用 ctx2.close()
  6. 调用 ctx2.lookup()。当前标识是 user2。

 


使用上下文查找已命名对象

对上下文使用的 lookup() 方法用于获取已命名对象。传递到lookup() 方法的参数是包含所需对象名称的字符串。清单 3-3 说明了如何检索名为ServiceBean 的 EJB。

清单 3-3 查找已命名对象
 try { ServiceBean bean = (ServiceBean)ctx.lookup("ejb.serviceBean");}catch (NameNotFoundException e) {// 绑定不存在}catch (NamingException e) {// 发生故障}

 


使用已命名对象获取对象引用

EJB 客户端应用程序从 EJB Home 中获取对 EJB 远程对象的对象引用。RMI 客户端应用程序从初始命名对象中获取对其他 RMI 对象的对象引用。WebLogic Server 将这两个初始命名对象识别为工厂。工厂是任何可以将引用返回到 WebLogic 名称空间中另一个对象的对象。

客户端应用程序对工厂调用方法,以获取对特定类的远程对象的引用。然后客户端应用程序对远程对象调用方法,传递所有需要的参数。

清单 3-4 包含获取远程对象、而后对该对象调用方法的代码片段。

清单 3-4 使用已命名对象获取对象引用
ServiceBean bean = ServiceBean.Home.create("ejb.ServiceBean")
Servicebean.additem(66);

 


关闭上下文

BEA 系统建议客户端使用上下文完成工作后,应当关闭上下文,以释放资源和避免内存泄漏。BEA 建议使用finally{} 块并包装 try{} 块中的 close() 方法。如果尝试关闭一个因错误而从未实例化的上下文,则 Java 客户端应用程序会引发异常。

在清单 3-5 中,客户端将关闭上下文,并释放正在使用的资源。

清单 3-5 关闭上下文
try {ctx.close();} catch () {//发生故障}

 


使用群集环境中的 WebLogic JNDI

WebLogic JNDI 的目的在于向 J2EE 服务提供命名服务,特别是 EJB、RMI 和 Java 消息服务(Java Messaging Service,简称 JMS)。因此,了解将对象绑定到群集环境中 JNDI 树的含义是很重要的。

下列部分讨论在群集环境中如何实现 WebLogic JNDI,并提供了一些可以使自己的对象在 JNDI 客户端可用的方法。

使用 RMI 和 JNDI 之间的关系启用 WebLogic 群集

WebLogic RMI 是允许 JVM 客户端从另一个 JVM 客户端访问 EJB 和 JMS 服务的可行性技术。RMI 存根控件将客户端传入的调用编组到 RMI 对象。为将 J2EE 服务提供给客户端,WebLogic 将特定服务的 RMI 存根控件绑定到其 JNDI 树的特定名称下。实例部署到群集中的其他服务器时,会更新 RMI 存根控件及 RMI 对象的其他实例位置。如果群集中的服务器失败,则会更新其他服务器的 JNDI 树中的 RMI 存根控件来反映服务器失败的信息。

客户端连接群集时,实际上是连接到群集中的一个 WebLogic Server。由于此 WebLogic Server 的 JNDI 树包含群集中其他 WebLogic Server 提供的所有服务(除了其自身服务)的 RMI 存根控件,因此群集对客户端显示为承载所有群集范围服务的 WebLogic Server。当有新的 WebLogic Server 加入群集时,群集中已有的每个 WebLogic Server 负责将有关自己服务的信息与新的 WebLogic Server 共享。通过从群集中的其他服务器收集到的信息,新服务器会创建自己的群集范围 JNDI 树的副本。

RMI 存根控件对在群集环境下实现 WebLogic JNDI 有着显著的影响:

  • RMI 存根控件相对较小。这允许 WebLogic JNDI 用很小的开销以服务器对服务器交互对话的方式,复制群集中所有 WebLogic Server 的存根控件。
  • RMI 存根控件充当跨群集进行复制的机制。虽然 RMI 对象实例被部署到单个 WebLogic Server,但是将跨群集复制存根控件。

使自定义对象对 WebLogic Server 群集可用

将自定义对象(非 RMI 对象)绑定到 WebLogic Server 群集中的 JNDI 树时,群集中的所有服务器都将复制该对象。但是,如果主机服务器发生故障,则从群集的 JNDI 树上删除自定义对象。除非再次绑定自定义对象,否则不复制该自定义对象。每次传播对自定义对象所做的更改时,需要先对自定义对象取消绑定,然后再重新绑定。因此,WebLogic JNDI 不能用作分布式对象缓存。可以结合使用第三方解决方案和 WebLogic Server 来提供分布式缓存。

假设自定义对象需要只允许仅在一个 WebLogic Server 中部署的 EJB 对其进行访问。很明显,不需要跨群集中的所有 WebLogic Server 复制此自定义对象。事实上,应当避免复制自定义对象,以免因进行不必要的服务器对服务器通信导致性能下降。要创建不跨群集中的 WebLogic Server 复制的绑定,在创建将自定义对象绑定到名称空间的上下文时,必须指定REPLICATE_BINDINGS 属性。清单 3-6 演示了如何使用REPLICATE_BINDINGS

清单 3-6 使用 REPLICATE_BINDINGS 属性
 Hashtable ht = new Hashtable();//关闭绑定的复制ht.put(WLContext.REPLICATE_BINDINGS, "false");try { Context ctx = new InitialContext(ht);//绑定对象ctx.bind("my_object", MyObect);} catch (NamingException ne) {//发生故障}

使用此技巧以及需要使用自定义对象时,必须明确获取 WebLogic Server 的InitialContext。如果连接到群集中的任意其他 WebLogic Server 时,JNDI 树将不显示绑定。

如果需要从群集中的任何一台 WebLogic Server 都能访问某个自定义对象,请将自定义对象部署到群集的每个 WebLogic Server 而不是复制 JNDI 绑定。

使用 WebLogic JNDI 复制绑定时,被绑定对象将被作为主机 WebLogic Server 拥有的对象来处理。如果主机 WebLogic Server 失败,则会从群集中所有 WebLogic Server 的 JNDI 树上删除自定义对象。此行为不利于使用自定义对象。

数据缓存设计模式

Web 应用程序的常用任务是缓存多个对象在一段时间内使用的数据,以避免产生与数据计算或与连接另一个服务有关的开销。

假设已设计了在单个 WebLogic Server 上执行良好的自定义数据缓存对象,并要在 WebLogic 群集中使用此对象。如果将数据缓存对象绑定到其中一个 WebLogic Server 的 JNDI 树上,默认情况下,WebLogic JNDI 会将此对象复制到群集中的任何其他一台 WebLogic Server 上。很重要的一点是,因为这不是 RMI 对象,但绑定到 JNDI 树(以及复制到其他 WebLogic Server)的是对象本身,而不是其中一台 WebLogic Server 所承载的单个对象实例的存根控件。不能根据 WebLogic Server 会在服务器之间复制自定义对象,从而假定自定义对象可用作分布式缓存。请记住,如果自定义对象所绑定到的 WebLogic Server 失败,则将从群集中删除该对象,并且,除非先取消绑定该对象,然后将其重新绑定到 JNDI 树,否则不会在群集中传播对该自定义对象所做的更改。

从性能和可用性方面来考虑,通常需要避免使用 WebLogic JNDI 的绑定复制将可用性要求较高的大型自定义对象复制到群集中的所有 WebLogic Server。因此,可以将自定义对象的单个实例部署到群集中的每台 WebLogic Server。将对象绑定到每台 WebLogic Server 中的 JNDI 树时,必须确保关闭绑定复制,如使自定义对象对 WebLogic Server 群集可用中所述。在此设计模式中,每台 WebLogic Server 都有自定义对象的副本,但要避免将大量的数据从一台服务器复制到另一台服务器。

不管使用何种方法,每个对象实例必须维护自己的逻辑,这样,不需要依赖群集中的其他数据缓存对象,便可更新其缓存。例如,假设客户端访问 WebLogic Server 中的数据缓存。这是缓存对象第一次被访问,所以它会计算或获取信息,并且保存信息副本以备将来的请求使用。现在假定另一个客户端连接群集以执行与第一个客户端相同的任务,不同之处只是连接到群集中的另一台 WebLogic Server。如果此特定的数据缓存对象是第一次被访问,则它需要计算信息,而不管群集中的其他数据缓存对象是否已经缓存该信息。当然,考虑到将来的请求,该数据缓存对象的实例应该能够查阅已保存的信息。

每个群集恰好一次的设计模式

有些情况下,要求具有在群集中只出现一次的服务。通过只在一台计算机上部署服务,可以达到此目的。对于 RMI 对象,可以使用 WebLogic JNDI 的默认行为来复制绑定(RMI 存根控件)以及可从群集中的所有 WebLogic Server 进行访问的单个对象实例。这称作固定服务。对于非 RMI 对象,确保将对象绑定到名称空间时使用的是REPLICATE_BINDINGS 属性。这种情况下,需要显式连接到主机 WebLogic Server 才能访问对象。也可以创建部署在相同主机 WebLogic Server (充当非 RMI 对象的代理)上的 RMI 对象。可以复制(使用默认的 WebLogic JNDI 行为)代理的存根控件,这允许连接到群集中的任何 WebLogic Server 的客户端都可以通过 RMI 代理来访问非 RMI 对象。

对于要求高可用性的服务,可以将 RMI 对象的自动迁移配置到另一个服务器上。有关自动迁移的详细信息,请参阅“使用 WebLogic Server 群集”中的服务器迁移

在群集环境中使用客户端的 WebLogic JNDI

对象的 JNDI 绑定可以出现在群集中其中一台 WebLogic Server 的 JNDI 树上,也可以被复制到群集中的所有 WebLogic Server 中。如果关注的对象只绑定在一台 WebLogic Server 上,则创建初始上下文时,必须通过将Context.PROVIDER_URL 属性设置为主机 WebLogic Server 的 URL 来显式连接主机 WebLogic Server,如使用 WebLogic JNDI 将 Java 客户端连接到单个服务器中所述。

然而,大多数情况下,关注的对象是群集服务或固定服务。因此,服务的存根控件显示在群集中每个 WebLogic Server 的 JNDI 树中。这种情况下,客户端不需要命名特定的 WebLogic Server 才能提供其命名服务。实际上,客户端最好只请求 WebLogic 群集提供命名服务,这样,WebLogic Server 中的上下文工厂可以从群集中选择最适合客户端的 WebLogic Server。

现在,可以使用由“群集地址”特性定义的群集的 DNS 名从 WebLogic 中选择命名服务提供程序。此特性定义客户端用于连接到群集的地址。此地址可以是映射到多个 IP 地址的 DNS 主机名,也可以是以逗号分隔的单个地址主机名或 IP 地址的列表。如果配置了网络通道,则可以为每个通道设置群集地址。请参阅使用 WebLogic Server 群集

通常,将返回到群集服务客户端的上下文作为故障转移存根控件来实现。当选定 WebLogic Server 发生故障(如通信失败)时,该存根控件可以以透明方式更改命名服务提供程序。

清单 3-7 说明客户端如何使用群集命名服务。

清单 3-7 使用 WebLogic 群集的命名服务
 Hashtable ht = new Hashtable();ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");ht.put(Context.PROVIDER_URL, "t3://acmeCluster:7001");try {Context ctx = new InitialContext(ht);// 做客户端的工作}catch (NamingException ne) {// 发生故障}finally {try {ctx.close();}catch (Exception e) {// 发生故障}}

指定作为提供程序 URL 一部分的 hostname 是指 ClusterAddress setting in a Cluster stanza of the config.xml file 定义的群集的 DNS 名。ClusterAddress 映射到此群集中提供的命名服务的主机列表。有关详细信息,请参阅“使用 WebLogic Server 群集”中的了解群集配置和应用程序部署

在清单 3-7中,群集名acmeCluster 用于连接群集中的任意一台 WebLogic Server。复制结果上下文,以透明地故障转移到群集中的任意一台 WebLogic Server。

指定与 WebLogic 群集的初始联系点另一个方法是提供以逗号分隔的 DNS 服务器名列表或 IP 地址列表。

  • 下例指定使用同一端口的 WebLogic Server 的列表:
    ht.put(Context.PROVIDER_URL,"t3://acme1,acme2,acme3:7001");

    所有 WebLogic Server 都在 URL 结尾处指定的端口上监听。

  • 下例指定使用不同端口的 WebLogic Server 的列表:
    ht.put(Context.PROVIDER_URL,"t3://node1:7001,node2:7002,node3:7003");

使用映射到多个服务器的 DNS 名时,WebLogic Server 取决于负载平衡的 DNS。

使用以逗号分隔的 WebLogic Server 节点的 DNS 名列表时,通过循环法方法完成故障转移,并将请求转到随机选择的服务器,如果该服务器响应失败,则该请求会转到列表上的下一个服务器。如果每台失败的服务器,此操作都会。

一旦客户端获取上下文,除非出现故障,否则不会发生其他负载平衡。这种情况下,WebLogic Server 将故障转移到群集的另一个节点。

远程客户端将从第一台可用服务器中获取上下文。群集中某台服务器的本地客户端永远不会转到远程服务器进行 JNDI 操作。

查找存根控件时,存根控件的第一个调用通常将转到获得上下文的服务器。如果存根控件是可群集的,则后续的调用会根据用户定义的负载平衡策略进行负载平衡。

有关 JNDI 和群集的详细信息,请参阅了解 WebLogic Server 群集

 


使用 J2EE 组件的 JNDI

虽然 J2EE 组件可能可以直接使用全局环境,但最好是使用组件环境。J2EE 应用程序中的每个 J2EE 组件都有自己的组件环境,该环境是根据组件的部署描述符中包含的信息进行设置的。

J2EE 组件能够使用下列代码查找组件环境:

Context ctx = new InitailContext();

Context comp_env = (Context)ctx.lookup("java:comp/env");

由于是在 J2EE 组件中工作,所以不需要设置散列表或环境对象来定义连接信息。

使用此上下文的方法与使用全局环境的方法相同,但是,所使用的名称是在组件的部署描述符中定义的名称。例如,部署描述符中有如下的 ejb-ref:

<ejb-ref>

...

<ejb-ref-name>ejb1</ejb-ref-name>

<ejb-ref-type>Session</ejb-ref-type>

<home>ejb1.EJB1Home</home>

<remote>ejb1.EJB1</remote>

...

</ejb-ref>

则可以查找使用 <ejb-ref-name> 设置所定义的名称,本例中为“ejb1”。

使用组件环境比使用全局环境来设置 JNDI 名称更具优势,因为在部署过程将解析所涉及的名称。这意味着,不必重新编写代码,就可以解决命名冲突。

有关设置和使用组件环境的详细信息,请参阅位于 http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf 的“J2EE Specification”。

 


设置外部 JNDI

外部 JNDI 是一个无需直接连接到远程树即可访问远程 JNDI 树上的对象的 API。

通过它,可以链接至另一台服务器上或提供程序(包括但不限于 WebLogic Server)上的 JNDI 树或者 java 程序中的 JNDI 树。一旦配置外部 JNDI 后,就可以使用位于其他位置的对象,这与使用绑定在 WebLogic server 实例的对象同样方便。

要配置外部 JNDI,请使用希望使用其对象的远程 JNDI 提供程序的地址创建 ForeignJNDIProvider,并创建用户名和密码访问这些对象。然后创建 ForeignJNDILinks 和 ForeignJNDIObjects,以设置本地 JNDI 树的名称和远程树的对象之间的关系。

有关如何配置外部 JNDI 的详细信息,请参阅“管理控制台联机帮助”中的创建外部 JNDI 提供程序

===-=================================================

WebLogic Clustering 系列之四
翻译:Sharetop(yancheng@sharetop.com)
配置 JDBC 和EJBs 的集群
本文主要包括以下几部分:
Ø 配置 JDBC 的集群
连接池集群配置
复合池集群配置
Ø JDBC 连接的Failover
Ø JDBC 连接的Load Balancing
Ø 配置 EJB 的集群
Ø WebLogic Server 中的EJBs
EJB Home Objects 的集群
EJBObjects 的集群
集群中的会话Bean
集群中的实体Bean
Ø 客户端代码示例
配置 JDBC 的集群
本节提供了用 Administration Console 配置JDBC 组件的方法指南。首先,需要创建一
个连接池(Connection Pool)以及复合池(Multipool),当然后者是可选的。然后才能创建
一个数据源(Data Source),因为在创建Datasource 时要求指定所绑定的连接池或复合
池。
连接池的集群
以下步骤设置一个基本连接池的集群:
1. 创建连接池。
2. 分配连接池到集群。
3. 创建数据源,指定所用的连接池。
4. 分配数据源到集群。
复合池的集群
以下步骤创建一个集群化的复合池,以提升性能或提供负载均衡的支持。
复合池是包含多个连接池的池(Pool of Pools)。在一个连接池里的所有连接都具有同一个
用户名,连接到同一个数据库,有同样的连接属性。但是,对于一个复合池中不同的连接
池中的连接,则可以用不同的用户甚至连接到不同的数据库实例上。通过两个数据库的同
步和镜像来实现Failover和Load Balancing。
WebLogic Clustering 系列之四
翻译:Sharetop(yancheng@sharetop.com)
1. 创建两个或多个连接池。
2. 为每个连接池分配 Target 到集群。
3. 创建复合池,指定包含的连接池。
4. 分配复合池到集群。
5. 创建数据源,指定所用的复合池。
6. 分配数据源到集群。
JDBC 连接的Failover
因为 JDBC 本身具有的事务特性,所以连接(Connection)不支持Failover。当一个
WebLogic Server 实例停止时,它所管理的Connection 也会失效,数据库将回滚事务。
但是,虽然connection 是不支持Failover 的,但是集群化的JDBC 很容易重新建立一个
新的连接。如果一个服务中止后,集群化的数据源可以向集群中的其它成员请求另一个有
效的连接,因为这个数据源具有Cluster-aware nature。
如果有一个同步镜像的数据库实例,可以使用复合池实现数据库的 Failover。在这种情况
下,如果客户端不能从一个连接池中获取有效连接(可能由于某种原因),它仍可以从复合
池中的其它连接池中获取连接。
注意: 如果客户端申请连接时,连接池里的连接都被占用了,此时WebLogic 并不会主动
从另一个连接池里分配一个连接,而是会抛出违例。
任何包含在复合池里的连接池都要求配置它的 Testing 属性(用于测试的表和连接保留时
间等)。因为复合池要依此来验证这个连接池是否有效。
JDBC 连接的Load Balancing
JDBC 连接的负载均衡要求使用复合池来实现。在创建复合池可以指定它采用的算法是为
了提高性能还是负载均衡的。
复合池中有一个它所包含的全部连接池的列表。如果没有配置复合池用于负载均衡,它总
是会使用列表中的第一个连接池,否则,则是使用round-robin 方式来决定使用哪一个连
接池。
配置 EJB的集群
EJB 的配置很简单,就是在发布EJB 的时候为它指定Target 为某个集群。
WebLogic Clustering 系列之四
翻译:Sharetop(yancheng@sharetop.com)
WebLogic Server 集群中的EJBs
本节提供了 EJB容器支持的集群服务信息。描述了在集群中EJB 行为和事务处理,以及
在布署描述文件中对EJB 在集群中的行为有影响的一些描述符。
WebLogic Server 集群EJB 通过提供特殊的Home 对象和EJB 对象来实现集群服务。
EJB Home Objects 的集群
在 WebLogic Server 集群中,服务器上的Home 对象在本地的表现为一个有集群意识
的代码存根(cluster-aware home stub),它能够感知到集群中的全部Home 对象。这
个集群的Home 存根实现了负载均衡,因为它支持在多个有效EJB 服务中分布式的查找
请求。同样,它也提供了对Failover的支持,因为它可以在一个服务中止时主动将请求路
由到其它有效的服务上。
所有的 EJB 类型- 无状态或是有状态的会话 Bean,以及实全Bean - 都能产生这样
的有集群意识的代码存根。是否生成集群代码存根,取决于weblogic -ejb-jar.xml 文件
中的home-is-clusterable 描述符,如果它为”true”(这也是缺省值)则ejbc 程序会
调用rmic 来自动生成这样的有集群感知能力的代码存根对象。
下图描述了集群环境下 EJB 的行为:
WebLogic Clustering 系列之四
翻译:Sharetop(yancheng@sharetop.com)
EJBObjects 的集群
类似的,在 WebLogic Server 集群中,EJBObject 的表现也是一个有镜像意识的
EJBObject 代码存根(replica-aware EJBObject stub),它同样地能意识到集群中全部
EJBObject 的多个拷贝。EJBObject 存根也实现了EJB方法调用的负载均衡和Failover。
例如,如果一个客户端正在调用某个特定WebLogic Server上的EJB 方法,这时这个
Server意外中止了,EJBObject 存根能够回滚这个调用,并重新调用集群中其它有效EJB
服务上的方法。
是否实现一个 replica-aware EJBObject stub 取决于EJB 对象的发布类型,对于实例
Bean 来说,如在发布时选择的缓存策略(cache strategy)。
集群中的会话 Bean
本节描述了有状态和无状态的会话 Bean 在集群的性能和限制。
Stateless Session EJBs
无状态会话 Bean同时提供了cluster-aware home stub 和replica-aware EJBObject
stub 两种代码存根。缺省地,WebLogic Server 在EJB方法调用上提供Failover 服务,
但是只能是方法调用之间的Failover。例如,如果一个意外中止事件发生在方法调用完成
后,或者企图连接的时候,WebLogic 提供Failover的自动支持。但是当意外中止发生在
方法执行过程中,WebLogic 不能自动提供Failover。
这种行为保证了数据库的更新不会因为 Failover而重复。比如,如果客户端正在插入数据
并完成了,如果此时发生Failover,WebLogic 会重新调用其它服务器上的同一个方法再
次插入数据。显然这样做存在严重的问题。
如果一个方法以某种方法保证了即使它被重复调用也不会产生上述问题,这种方法也被称
为"idempotent"。在这种情况下,WebLogic 也提供了方法过程内的Failover,只要修
WebLogic Clustering 系列之四
翻译:Sharetop(yancheng@sharetop.com)
改 weblogic -ejb-jar.xml 文件中的stateless-bean-methods-are-idempotent
描述符即可,设置它的值为”true”。
下面这个图描述了无状态的会话 Bean 在集群中的行为:
Stateful Session EJBs
同样有状态的会话 Bean 也通过cluster-aware home stubs 实现了EJB查找的Failover
和负载均衡,在这点上与无状态的会话Bean 没什么不同。但是有状态的会话Beanr
replica-aware EJBObject stubs 会涉及到一个状态维护的问题。WebLogic Server 集
群提供了一个对客户端完全透明的状态维护机制:它会同步地把活动的Server 中的有状
态会话Bean 的当前状态复制到第二个备份Server 中。
集群中的实体 Bean
同样的,实体 Bean 也能够使用cluster-aware home stubs 如果设置
home-is-clusterable 描述符为"true" ,而EJBObject stub 的行为也取决于
weblogic -ejb-jar.xml 文件中的cache-strategy 描述符。
集群中的读-写实体Bean
读写实体 Bean 在集群中的行为与它不在集群中的行为是一致的:
§ 多个客户端可以在事务中使用这个 Bean。
§ ejbLoad() 总是开始一个事务
§ ejbStore() 在事务结束时被调用
WebLogic Clustering 系列之四
翻译:Sharetop(yancheng@sharetop.com)
客户端代码示例
在连接一个集群的 JDBC 数据源或EJB 时,客户端的方法如下:
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL,
"t3://yancheng:8001,yancheng:9001");
// Get a context for the JNDI look up
ctx = new InitialContext(ht);
javax.sql.DataSource ds
= (javax.sql.DataSource) ctx.lookup ("arison.fsi.datasource.demo2");
注意这里的 Context.PROVIDER_URL 值的格式,在协议后是集群中多个机器:端口的列表,
中间用逗号分隔。如本例中的 t3://yancheng:8001,yancheng:9001。对于EJB 或JDBC
都可以通过此方法在集群中在JNDI 的方式查找相应服务。

原创粉丝点击