集群策略--集群(clustering)

集群(clustering)这个词使用非常混乱。这里我们首先给出一个较为科学的阐述,并以这个阐述为主线来叙述、探讨相关问题。

集群可分为三种类型:科学集群、高可用性集群、负载均衡集群。

科学集群(Scientific Clustering,简称SC):使用特殊的软硬件技术将大量的计算能力有限的机器连接成计算能力巨大的系统。此类集群一般用于解决计算量巨大的复杂的科学问题。基于硬件的解决方案有Intel的Giganet cLAN;比较有名的研究项目有Beowulf、Virginia U的Legion、Sandia National Lab的Cplant、HongKong U的JESSICA 2等;比较知名的产品有TurboLinux公司的enFuzion。

高可用性集群(High Availability Clustering,简称HAC):使用厂商供应的或定制的、冗余的软硬件来保证系统的可用性。此类集群一般用于避免系统的单点失效。涉及的技术主要包括:持续可用、容错、单点失效、失效恢复。下为HP OpenVMS示例图(来自http://h71000.www7.hp.com/openvms/products/clusters/index.html)。

HP OpenVMS示例图

图 4.1. HP OpenVMS示例图


负载均衡集群(Load Balance Clustering简称LBC):通过特定的软硬件将系统负载合理地分配给集群中的服务器。此类集群一般用于水平提升系统的服务能力。对于软件负载均衡方案,比较知名的项目有LVS;比较知名的产品有TurboLinux的TurboCluster、Platform Computing 的 LSF 批处理、Resonate Dispatch 系列等。对于硬件负载均衡方案,由于硬件负载均衡器品种繁多,用户有很大的选择余地。下为LVS的Web Cluster架构图(来自www.linuxvirtualserver.org)。

LVS的Web Cluster架构图

图 4.2. LVS的Web Cluster架构图


现实的集群系统往往是以上三种类型中的一种或者多种的结合。而科学集群,由于它特定的应用域、涉及高端软硬件技术、昂贵的造价,很少应用在主流的商业系统中。所以,常见的集群系统往往是HAC或LBC或两者的结合。

4.17.1.2. JavaEE和集群

前面,我们将集群分为SC、HAC、LBC三种类型。大体来说,这种分类法的依据是它们各自的用途。而从集群方案具体实施依赖硬件或软件来说,各种类型的集群又可分为硬件集群方案、系统级别集群方案、应用级别集群方案,一个现实的方案可能是上述三种方案中的一种或者多种的结合。譬如现在我们需要做一个Web负载均衡集群,那么我们可以选择(当然每种方案具体实施花样百出、不一而足,本文只是介绍最常见的实施)的方案有:

  1. 硬件集群方案

    一般来说,硬件负载均衡器充当前端,分发客户请求到Web Server,Web Server响应返回给硬件负载均衡器,最终由硬件负载均衡器返回给客户(当然,路径外返回技术使得响应能够直接返回给客户)。通常,硬件负载均衡器工作在OSI参考模型的第2、3、4、7层,而4、7层是最常见的。此方案功能较强、效率较高、故障率较低。

  2. 系统级别的集群方案

    通常,这种方案和基于硬件的负载均衡方案工作方式非常相似。只是前端以软件的形式出现。当然,一般来说,这种方案效率会低于硬件方案。值得一提的是,MS的负载均衡技术有些特别,它不需要前端代理,但是你需要在各个后端服务器上安装特定驱动。工作模式简单示意如下:

  3. 应用级别的集群方案

    这种方案,前端以软件负载均衡器的形式出现;它和系统级别集群方案不同的是,客户请求的处理、响应等行为工作在应用层(OSI参考模型的第7层)。理论上说,这种方案方便,不过在负载较重时,前端会成为瓶颈而导致效率较低。

很显然,目前JavaEE Application Server厂商提供的集群方案(主要包括Web集群、JNDI集群、EJB集群、JMS集群)都属于应用级别的集群方案。

4.17.2. Apusic 集群

Apusic作为专业的、成熟的JavaEE应用服务器,它提供了整套的、灵活的、有效的集群方案,是金融、电信、电力等行业的基于JavaEE技术的高性能、高可用、可扩展系统的保障。

Apusic集群主要包括Web集群、JNDI集群、EJB集群、JMS集群。

4.17.2.1. Web集群

一般来说,Web集群试图解决两个问题:客户请求的负载均衡和session的高可用。Apusic Web集群为这两个问题提供了灵活、全面的解决方案。

客户请求的负载均衡是指客户的请求依赖特定算法被合理地分配给多台Web Server来处理。

session的高可用是指当某台Web Server失效,这台Web Server服务的客户的请求会被透明地转发给其它有效Web Server,而会话状态(session)依然可用。我们把集群范围内具有高可用性的session称为集群session。

4.17.2.1.1. Web集群方案

对于只需要负载均衡集群的用户,有两种方案:

  1. 前端,采用硬件负载均衡器;后端,部署多台Apusic Web Server。

  2. 前端,部署Apusic LoadBalancer;后端,部署多台Apusic Web Server。

Apusic应用服务器可配置成Apusic LoadBalancer,充当软件负载均衡器。

对于同时需要负载均衡和Session高可用的用户,有两种方案:

  1. 前端,将Apusic应用服务器配置成Apusic LoadBalancer;后端,部署多台Apusic Web Server,并启用Session迁移功能。

  2. 前端,采用硬件负载均衡器;后端,部署多台Apusic Web Server,并启用Apusic Web Server 的集群session功能。

另外,Apusic Web Server还可以无缝、高效、稳定地与其它常用Web Server(譬如Apache、IIS)进行整合。所以,事实上,Web集群还具有以下方案可以选择。

对于只需要负载均衡集群的用户,更多方案:

  1. 前端,采用Apache Web Server,配置支持AJP1.3的JServ或jk、jk2模块或者采用Apache Proxy模式;后端,部署 多台Apusic Web Server,配置AJP服务。

  2. 前端,采用IIS,并配置ACP模块;后端,部署多台Apusic Web Server。

对于需要负载均衡和session高可用的用户,更多方案:

  1. 前端,采用Apache Web Server,配置支持AJP1.3的JServ或jk、jk2模块;后端,部署 多台Apusic Web Server,配置AJP服务,同时启用集群Session功能。

  2. 前端,采用IIS,并配置ACP模块;后端,部署多台Apusic Web Server,并且启用集群 session功能。

4.17.2.1.2. Web集群相关配置

配置Apusic负载平衡。请参考第 4.6 节 “配置负载均衡”

4.17.2.1.3. Session集群配置

为了集群Session,你需要在%DOMAIN_HOME%/config/apusic.conf中配置服务ClusterService,示例如下:

...
<SERVICE CLASS="com.apusic.cluster.ClusterService">
    <ATTRIBUTE NAME="ClusterName" VALUE="ApusicCluster"/>
    <ATTRIBUTE NAME="LoadWeight" VALUE="100"/>
</SERVICE>
...

同时,你需要设定SessionService的Distributable和Replicable属性为True,示例如下:

...
<SERVICE CLASS="com.apusic.servlet.http.session.SessionService">
    <ATTRIBUTE NAME="DefaultSessionTimeout" VALUE="3600"/>
    <ATTRIBUTE NAME="MaxSessionsInCache" VALUE="1024"/>
    <ATTRIBUTE NAME="SessionInvalidateCheckInterval" VALUE="60"/>
    <ATTRIBUTE NAME="SessionSwapCheckInterval" VALUE="30"/>
    <ATTRIBUTE NAME="Distributable" VALUE="True"/>
    <ATTRIBUTE NAME="Replicable" VALUE="True"/>
</SERVICE>
...

值得一提的是,Apusic Session集群采取instant replication,即某节点的Session操作是即使传播(同步)到集群中的其它节点的;而有些厂商的集群Session同步采取非即时的方式,这种方式通常被认为可以一定程度降低服务器消耗和网络消耗,但是,很显然,它降低了Session可用性。还有一个比较常见的场景是新节点加入工作中的集群,这种情况下,新节点的Session会自动与集群同步。

整合Apache. 请参考第 4.9 节 “使用Apache作为Web代理”

整合IIS. 请参考第 4.10 节 “使用Microsoft IIS作为Web代理”

ClusterService详解. 如上所示,集群Session关键之一就是配置ClusterService服务:

...
<SERVICE CLASS="com.apusic.cluster.ClusterService">
    <ATTRIBUTE NAME="ClusterName" VALUE="ApusicCluster"/>
    <ATTRIBUTE NAME="LoadWeight" VALUE="100"/>
</SERVICE>
...

事实上,ClusterService是Apusic集群的核心,Web集群、JNDI集群、EJB集群都基于它,它的主要作用之一就是发现、维护集群节点。下面,着重讨论属性ClusterName,LoadWeight会在EJB集群部分阐述。

示例应用场景:LAN某个网段中部署4台Apusic服务器(S1、S3、S3、S4),它们均配置了 ClusterService服务,并且设定属性ClusterName为ApusicCluster,那么,这4台服务器纳入一个集群;但是,你可能希望S1、S3纳入一个集群,S2、S4纳入一个集群,那么,最简单的方法就是为ClusterService服务设定不同的ClusterName属性。这种做法也叫做分区(partition)。

4.17.2.2. JNDI集群

JNDI作为JavaEE的基础技术,JNDI集群往往是其它上层集群技术的必要条件。

4.17.2.2.1. 本地JNDI和JNDI集群

我们知道,JNDI命名是以层次结构来组织的,在示意图中,往往用树来表达,所以称为JNDI树。

那么,JNDI集群又是怎么回事呢?

JNDI集群是Apusic服务器提供的一个服务,一旦启用这个服务,集群的各节点(指Apusic服务器)都拥有一个集群JNDI树,它有别于本地JNDI树,事实上,在JNDI集群节点中,这两棵树是同时存在的,那么它们的区别和联系又在哪里?

各节点的本地JNDI树是彼此独立的,遵循JavaEE JNDI标准语义、习惯用法,而它们的集群JNDI树之间会遵循如下规则协作。

  1. 在集群中,某个服务器节点集群JNDI树上的操作都会传播到其它节点的集群JNDI树上。譬如在某节点bind(“a”,”a”),那么其它节点的集群JNDI树上也会存在名值对(“a”,”a”)。当然,这里可能出现名字冲突的问题,譬如, A节点首先bind(“a”,”a”),并且传播到其它节点,随后,B节点bind(“a”,”aa”),那么会出现什么情况呢?对于这种情况,我们只会将B节点的a与aa绑定,而集群内的其它节点保持不变。如果你需要集群范围所有的集群JNDI树上的名值对(“a”,”a”)全部更新为(“a”,” aa”),你需要使用rebind方法。

  2. 当你持有一个集群JNDI上下文,并且使用它lookup的时候,它首先在集群JNDI树上搜索,搜不到,还会到本地JNDI树上搜索(如上图所示)。

4.17.2.2.2. JNDI集群配置

启用Apusic JNDI集群服务,你需要在%DOMAIN_HOME%/config/apusic.conf中配置ClusterNameService服务,片断如下:

<SERVICE CLASS="com.apusic.naming.cluster.ClusterNameService"/>

当然,由于ClusterService服务是ClusterNameService服务的基础,所以,你需要保证在%DOMAIN_HOME%/config/apusic.conf中已经配置ClusterService服务,示例片断如下:

<SERVICE CLASS="com.apusic.cluster.ClusterService">
    <ATTRIBUTE NAME="ClusterName" VALUE="ApusicCluster"/>
    <ATTRIBUTE NAME="LoadWeight" VALUE="100"/>
</SERVICE>
4.17.2.2.3. JNDI集群客户端

上面提及,无论使用本地JNDI还是集群JNDI,首先我们必须获取相应的JNDI上下文(一般都是初始上下文)。

本地JNDI的使用遵循JNDI标准,示例代码片断:

Hashtable env = new Hashtable();
//You can specify Apusic-specific properties here.
env.put(Context.INITIAL_CONTEXT_FACTORY,”com.apusic.naming.jndi.CNContextFactory);
env.put(Context.PROVIDER_URL,”iiop://192.168.6.55”);
//something omitted.
…
Context ctx = new InitialContext(env);

如果你试图获取集群JNDI初始上下文而不是本地JNDI初始上下文,那么你需要在客户端设定环境变量:

apusic.naming.clustering=true

那么在哪里设定上述环境变量呢?你可以使用命令行参数;你也可以通过编码在JNDI初始上下文属性中指定;甚至,你可以将之写入JNDI实现jar包的jndi属性配置文件中(不推荐)。

下面是第二种方式的示例代码片断:

Hashtable env = new Hashtable();
//You can specify Apusic-specific properties here.
env.put(“apusic.naming.clustering”,”true”);
env.put(Context.INITIAL_CONTEXT_FACTORY,”com.apusic.naming.jndi.CNContextFactory);
env.put(Context.PROVIDER_URL,”iiop://192.168.6.55”);
//something omitted.
…
Context ctx = new InitialContext(env);
4.17.2.2.4. JNDI 负载均衡和JNDI失效恢复

什么是JNDI负载均衡(Load Balance)和JNDI失效恢复(Fail-Over)?它试图解决的是什么问题?

场景:某公司C部署了一台Apusic服务器S1,并且通过本地JNDI发布了服务(n,s),系统客户端遵循常规JNDI用法,指定S1为provider。显然,服务器都存在失效的可能,而且,随着业务的扩展,服务量的增加,一台服务器,已经不能满足需求,服务质量(系统响应时间和系统可用性)急待提高。公司又增加两台服务器S2、S3,S2、S3同样通过本地JNDI发布了服务(n,s),此时,系统客户端怎样和S1、S2、S3交互成为问题的关键所在。理想的情况是,系统客户端的服务请求被合理地分配到S1、S2、S3上,一旦,其中一台或多台服务器失效,服务请求会透明地、合理地被分配到剩下的有效的服务器上。

上述场景中的服务请求被合理地分配到多台服务器的行为就称作JNDI负载均衡,而一台或多台服务器失效后,服务请求通明、合理地被分配到剩下地有效的服务器上的行为就称作JNDI失效恢复。

Apusic JNDI具有JNDI负载均衡和失效恢复能力。

为了启用Apusic JNDI负载均衡和失效恢复能力,你只需要在客户端设定环境变量java.naming.provider.url=<provider-list>,如2.2.3节所述,你可以通过多种方式来设定。推荐方式是在JNDI初始上下文的PROVIDER_URL属性中指定<provider-list>,<provider-list>格式示例如下:

iiop://S1:6888,S2:6888,S3:6888

当然S1,S2,S3可以用IP替代。

显然,硬编码总是缺乏灵活性,所以,Apusic还提供了JNDI provider的发现(discovery)功能,你不需要通过PROVIDER_URL属性指定任何provider,你只需要在客户端设定如下环境变量:

apusic.naming.discovery=true
apusic.naming.discovery.address=230.0.0.2
apusic.naming.discovery.port=1500
apusic.naming.discovery.timeout=5000
apusic.naming.discovery.cluster_name=ApusicCluster

其中,apusic.naming.discovery=true是必须的,剩下的四个环境变量,除apusic.naming.discovery.cluster_name,其它三个如果省略,那么如上默认值会被采用。当然,别忘了在%DOMAIN_HOME%/config/apusic.conf中配置DiscoveryService服务,片断如下:

<SERVICE CLASS="com.apusic.net.DiscoveryService">
    <ATTRIBUTE NAME="GroupAddress" VALUE="230.0.0.2"/>
    <ATTRIBUTE NAME="GroupPort" VALUE="1500"/>
</SERVICE>

最后,着重说一下环境变量apusic.naming.discovery.cluster_name,如果你需要限定发现(discovery)的范围(某个partition,即某个集群),那么你可以将它设定为某集群名(对应于ClusterService服务的ClusterName属性)。

在阐述JNDI负载均衡和JNDI失效恢复的过程中,我们似乎没有提及集群JNDI?没错,负载均衡、失效恢复、discovery功能对于本地JNDI是有效的,当然,对于集群JNDI,它们依然有效,只是,你别忘了在客户端设定环境变量:apusic.naming.clustering=true。

4.17.2.3. EJB集群

Apusic应用服务器支持EJB3.0,同时兼容EJB2.x、EJB1.x。EJB集群是解决大规模、具有厚重而复杂的商业逻辑、高性能、高可用、高水平可扩展的JavaEE系统的良好方案。Apusic为SessionBean、EntityBean集群提供简洁有效、独具特色的支持。

Apusic EJB集群主要面向两个问题:负载均衡和高可用性。值得注意的是,EJB集群一般都是针对EJB远程调用而言,而非本地调用(包括集群节点内部使用远程接口,因为对于这种情况,Apusic会自动优化成本地调用)。以下叙述,对于Home接口、Bean接口,如果如果没特殊说明,均指远程的。

4.17.2.3.1. EJB负载均衡和EJB高可用性

首先,以EJB2.x编程模型为例,我们看看SessionBean、EntityBean的典型应用模式。

一个典型的SessionBean应用代码片断:

…
Context ctx  = …;
CounterHome counterH =  (CounterHome)
PortableRemoteObject.narrow(ctx.lookup(“ejb/Counter”),CounterHome.class);
Object o =  counterH.create(/*may be ,some initial states for stateful session bean.*/);
Counter counter  =  PortableRemoteObject.narrow(o,Counter.class);
counter.add(1);
counter.minus(100);
…

一个典型的EntityBean应用代码片断:

…
Context ctx = …;
AccountHome accountH = (AccountHome)
PortableRemoteObject.narrow(ctx.lookup(“ejb/Account”),AccountHome.class);
Object o = accountH. findByPrimaryKey(new AccountPK(“ISN”));
Account account = PortableRemoteObject.narrow(o,Accout.class);
account.deposit(1);
account.withdraw(100);
…

从上面代码片断我们可以看出,典型的EJB应用,首先获取Home接口,然后通过Home接口获取Bean接口,最后通过Bean接口调用业务方法完成商业计算(如下图)。

那么,EJB负载均衡、EJB高可用性是怎么回事?

沿袭负载均衡一贯的语义,EJB负载均衡指EJB调用通过特定算法分配到多台应用服务器的行为。这里的EJB调用指对EJB Bean接口的调用。然而,Apusic EJB集群还支持Home接口的负载均衡。

目前,Apusic EJB集群支持的负载均衡算法有:

  1. RANDOM

    随机选择集群有效节点中的一个

  2. ROUND_ROBIN

    循环地、依次地选择集群有效节点中的一个

  3. WEIGHTED

    根据集群节点预先设定的负载权重进行选择。权重通过服务ClusterService的LoadWeight属性设置,范围是[1,100]。一般来说,WEIGHTED用于非对称集群,譬如,集群中有两台服务器S1、S2,S1计算能力强于S2,那么可以根据计算能力的比例为S1、S2设置恰当的权重值,从而,使得计算能力强的服务器接收、处理更多的请求。

  4. STICKY

    在获取Bean接口、通过Bean接口调用业务方法的时候,随机选择一个节点,此后,获取Bean接口、调用Bean接口的业务方法的调用全部发送到这个节点,除非这个节点失效。

    EJB高可用性指在某集群节点失效的时候,对它的EJB Home接口的调用或者Bean接口的调用会透明地转移到其它有效节点。

4.17.2.3.2. EJB集群配置

事实上,EJB集群的配置是相当简单的,你只需要在apusic-application.xml的Bean配置中添加如下格式的片断:

<cluster-config>
  <clustered>true</clustered>
  <home-load-balance-policy>ROUND_ROBIN</home-load-balance-policy>
  <object-load-balance-policy>ROUND_ROBIN</object-load-balance-policy>
</cluster-config>

其中<home-load-balance-policy>配置Home接口的负载均衡算法。<object-load-balance-policy>配置Bean接口的负载均衡算法。当然,以上两个配置是可选的,你可以简单添加片断:

<cluster-config>
  <clustered>true</clustered>
</cluster-config>

此时,Apusic会根据Bean的类型决定Home接口和Bean接口的负载均衡算法。决策为所有类型的Bean,Home接口采用ROUND_ROBIN算法;SLSB和只读EntityBean的Bean接口采用ROUND_ROBIN算法;SFSB和非只读EntityBean的Bean接口采用STICKY算法。以下是集群SLSB的apusic-application.xml的片断:

<apusic-application>
  <module uri="">
    <ejb>
      <session ejb-name="GreetingBean">
     <jndi-name>ejb/GreetingHome</jndi-name>
     <local-jndi-name>ejb/GreetingLocalHome</local-jndi-name>
     <security-mechanisms/>
        <cluster-config>
          <clustered>true</clustered>
          <home-load-balance-policy>ROUND_ROBIN</home-load-balance-policy>
          <object-load-balance-policy>ROUND_ROBIN</object-load-balance-policy>
        </cluster-config>
      </session>
    </ejb>
  </module>
</apusic-application>

当然,别忘了,在%DOMAIN_HOME%/config/apusic.conf中配置ClusterService服务,示例如下:

<SERVICE CLASS="com.apusic.cluster.ClusterService">
    <ATTRIBUTE NAME="ClusterName" VALUE="ApusicCluster"/>
    <ATTRIBUTE NAME="LoadWeight" VALUE="100"/>
</SERVICE>
4.17.2.3.3. EJB集群实践
  • 关于Home接口和Bean接口负载均衡算法的选择

    理论上,任何类型Bean的Home接口和Bean接口都可以采用RANDOM、ROUND_ROBIN、WEIGHTED、STICKY算法。不过,显然,集群节点计算能力不对称、各种Bean的特性、各种Bean集群的特定实现方式等等因素都会影响甚至决定均衡算法的选择。

    1. 如果集群节点计算能力不对称,优先考虑WEIGHTED算法。

    2. 由于Apusic SFSB、非只读EntityBean集群的特定实现方式,所以它们的Bean接口最好采用STICKY算法。

  • 关于集群节点内部的EJB调用

    上面,我们提到,一般来说,EJB集群针对远程调用而言。同时,存在这样的事实:对于节点内部的EJB远程调用,Apusic会自动将之优化成本地调用。所以,包括Web-EJB、EJB-EJB等方式在内的集群节点内部的EJB调用(无论使用远程接口还是本地接口),最终都变成本地调用,同时负载均衡和高可用性特性消失。

  • 关于EntityBean一定程度的状态同步

    Apusic EJB 容器支持EJB2.1规范提及的A、B、C三种commit-time option。很显然,基本上,EntityBean集群场景是不符合option A的假定,更重要的是,Apusic EJB集群依赖数据库同步,所以,一般来说,concurrency-strategy设定为Exclusive并且force-refresh设定为False,这样的方案绝对不应采用,而Concurrency-strategy采用Parallel策略是推荐方案。

  • 关于安全角色的传播

    要使节点间EJB调用的安全角色能够传播,必须使用一致的认证密钥,即%DOMAIN_HOME%/config/authkey.dat必须一致。可以先启动一个Apusic服务器,生成config/authkey.dat文件,然后将此文件复制到其他服务器。

4.17.2.4. JMS集群

JMS是JavaEE相当重要的一部分,它为开发异步、可靠、高性能、灵活的系统提供支持。目前广泛应用于EAI、EDI等领域。Apusic JMS集群主要包括消息路由和集群队列功能。

4.17.2.4.1. 消息路由

消息路由一般用来解决在发送消息的客户端和消息目的地不能直接连通的情况下,依赖特定算法,JMS网络中的一个或多个中间消息路由器(Router)组成的能够到达消息目的地的最优通路会被选出并负责转发消息。详见第 4.12 节 “消息服务配置”

4.17.2.4.2. 集群队列

基于JMS的系统同样存在负载均衡和可用性的问题。集群队列基于消息路由技术,它能够很好的解决这两个问题。

集群队列是指JMS网络中的任何一个节点上定义的消息队列都将被其他节点所共享,通过任何节点向一个集群队列发送消息都是等效的,对客户来说无法察觉是否正在使用集群,集群中网络拓扑结构发生变化对客户端也没有任何影响。

集群队列具有高可用性:JMS网络中单个节点失效或部分网络无法连通时并不影响集群队列的使用。

集群队列具有负载均衡特性:在发送消息时,根据各节点的负荷情况,负载会被合理分配,从而使节点处理能力和网络带宽被充分利用。

  • 配置集群队列

    要使用集群队列,你只需要在jms.xml中,为某个队列添加clustered属性,示例片断:

    <queue clustered="true">
    <queue-name>clusteredQueue</queue-name>
    </queue>

    当然,首先,你需要配置JMS网络。详见第 4.12 节 “消息服务配置”

  • 使用集群队列

    典型的JMS应用中,无论发送、接收消息,都需要通过某种方式获取目的地(Destination,为Queue或者Topic),一般,我们通过JNDI来获取,示例代码片断如下:

    Context ctx = …;
    Session ssn = …;
    Queue queue = (Queue)ctx.lookup(“TestQueue”);
    …

    那么我们又怎样获取集群队列呢?其实,很简单,我们需要通过JMS Session接口的方法Queue createQueue(String queueName)来获取,以上面注册的clusteredQueue为例,代码片断如下:

    Session ssn = …; //get session instance
    Queue queue = ssn.createQueue(“clusteredQueue”);
    …
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值