使用此技巧以及需要使用自定义对象时,必须明确获取 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 说明客户端如何使用群集命名服务。
指定作为提供程序 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 群集。