您的位置:首页 > 其它

翻译] JBoss 4.0.5 应用服务器集群指南(一)

2007-04-23 12:03 471 查看

1概述

集群允许一个应用同时运行在多个并发的服务器。负载分布在不同的服务器,即使有个别服务器崩溃,应用程序还可以通过别的服务器节点访问。集群是企业级应用的关键技术,可以通过简单地增加节点来提升性能。

JBoss支持集群,启动一个JBoss集群的最简单的方式是,使用run-call命令在局域网内启动多个JBoss实例。这些服务器实例,都使用all配置集,自动地构建一个集群。

1.1定义

一个集群是由一系列节点组成。在一个JBoss集群中,一个节点是一个JBoss服务器实例,要构建一个集群,必须将几个JBoss服务器实例组合在一起。在一个局域网可能有多个集群,为了区分他们,每个集群必须有唯一的名称。

下图构建一个网络,包含三个集群。节点可以在任何时候添加到集群或者从集群中



注意:

一个JBoss服务器实例可以同时在多个集群,但是不推荐这样做,因为会增加管理复杂性。

JBoss服务器实例通过deploy/cluster-service.xml文件中的ClusterPartitionMBean指定属于哪一个集群。所有有同样的ClusterPartitionMBean配置的节点属性同一个集群。因此,如果想在同一个局域网构建两个集群,只需要创建两个不同的ClusterPartition配置即可。如果某一个节点启动时,集群还不存在,会创建这个集群,同时当属于一个集群的所有节点移除时,集群也会被移除。

下面的示例是JBoss发布包的缺省定义,通过使用此缺省集群设置启动服务器,将可以构建一个缺省集群名称为DefaultPartition的集群。

<mbeancode="org.jboss.ha.framework.server.ClusterPartition"

name="jboss:service=DefaultPartition">

>

<attributename="PartitionName">

${jboss.partition.name:DefaultPartition}

attribute>

>

<attributename="NodeAddress">${jboss.bind.address}attribute>

>

<attributename="DeadlockDetection">Falseattribute>

<!---Maxtime(inms)towaitforstatetransfertocomplete.</sp-->

Increaseforlargestates-->

<attributename="StateTransferTimeout">30000attribute>

>

<attributename="PartitionConfig">

......

attribute>

mbean>

xml代码
这里省略了详细的JGroups协议配置,JGoups处理底层的节点之间的点对点通信,稍后将讨论其具体配置。ClusterPartitionMBean可配置的属性包括:

PartitionName缺省值是DefaultPartition,可选属性,用来指定集群的名称。

NodeAddress设置节点的IP地址。

DeadlockDetection缺省值为false,设置JGroups是否基于每个请求都运行消息死锁检测算法。

StateTransferTimeout缺省值是30000,设置集群之间的状态复制的超时值。

PartitionConfig指定JGourp配置选项。

一个集群包含的所有节点,必须有同样的PartitionName和ParitionConfig元素。改变某些节点的这两个元素将导致集群分离,通过改变ParitionConfig是更容易一些。

可以通过集群中的任何一个节点的JMX控制台查看当前集群信息(比如:http://hostname:8080/jmx-console),然后点击jboss:service=DefaultPartitionMBean,将可以看到当前集群的所有节点的IP地址列表。

注意

Acluster(partition)containsasetofnodesthatworktowardasamegoal.Someclusteringfeaturesrequiretosub-partitiontheclustertoachieveabetterscalability.Forexample,let'simaginethatwehavea10-nodeclusterandwewanttoreplicateinmemorythestateofstatefulsessionbeansonall10differentnodestoprovideforfault-tolerantbehaviour.Itwouldmeanthateachnodehastostoreabackupofthe9othernodes.Thiswouldnotscaleatall(eachnodewouldneedtocarrythewholestateclusterload).Itisprobablymuchbettertohavesomekindofsub-partitionsinsideaclusterandhavebeansstateexchangedonlybetweennodesthatarepartofthesamesub-partition.ThefutureJBossclusteringimplementationwillsupportsub-partitionsanditwillallowtheclusteradministratortodeterminetheoptimalsizeofasub-partition.Thesub-partitiontopologycomputationwillbedonedynamicallybythecluster.

1.2服务架构

对于应用程序开发人员来讲,可能更关心集群的架构,JBoss支持两种类型的集群架构,一种是客户端的拦截器架构,比如代理和存根,还有一种是负载平衡器。

1.2.1客户端拦截器架构

JBoss应用服务器提供的大多数远程服务,包括JNDI,EJB,RMI等都要求客户端获取一个存根对象。存根对象由服务器生成,实现服务接口。客户端在本地调用存根对象,这些调用自动进行网络路由,激活服务器管理的服务对象。在一个集群环境中,服务器生成的存根对象也是一个拦截器实现,知道如何在集群包含的节点中路由请求。存根对象知道如何查找合适的服务器节点,编码调用参数,解码调用结果,并返回结果给客户端。

存根拦截器包含集群的相关信息,比如,所有可用的服务器节点的IP地址,负载平衡算法,以及当某个目标节点不可用时如何处理请求。每个请求中,服务器节点将用集群的最近的改变信息更新存根拦截器。比如,一个节点从集群中移除,当每个存根拦截器连接到任何一个激活的节点时,都将更新最新的配置信息。所有基于存根的操作对于客户来讲都是透明的,客户端拦截器集群架构如下图所示:



1.2.2负载平衡器

别的JBoss服务,特别是HTTPWEB服务,不要求客户端下载任何东西。客户直接通过某个通信协议发送请求并接受响应,比如HTTP协议。这种情况下,一个负载平衡器用来处理所有的请求并将这些请求派发给集群中的节点。负载平衡器通常是集群的一部分,它知道集群配置和恢复策略,客户端只需要知道负载平衡器。负载平衡器架构如下图所示:


负载平衡器架构的一个潜在的问题是负载平衡器是所有请求的唯一入口,必须保证高的可用性。

1.2.3负载平衡策略

客户拦截器架构和负载平衡器架构都使用负载平衡策略确定由哪一个服务器节点发送一个新的请求。下面描述JBossAS的负载平衡策略。

1.2.3.1JBossAS3.0.x

JBoss3.0.x中有如下两个负载平衡选项可用:

Round-Robin(org.jboss.ha.framework.interfaces.RoundRobin):每次调用被派发给一个新的节点,第一个节点是随机选择的。

FirstAvailable(org.jboss.ha.framework.interfaces.FirstAvailable)::第一个可用的节点选为主节点,服务于随后每一个调用,主节点的选择是随机的。当集群中的节点发生变化时(因为节点启动或者停止),除非当前主节点依然可用,将重新选择一个可用的节点作为主节点。每个客户端拦截器或负载平衡器独立选择自己的主节点。

1.2.3.2JBossAS3.2+

JBoss3.2+中增加了一个新的负载平衡选项"FirstAvailableIdenticalAllProxies"(org.jboss.ha.framework.interfaces.FirstAvailableIdenticalAllProxies),此选项和"FirstAvailable"策略有类似的策略,唯一的区别是选择的主节点被所有的客户端拦截器共享。

JBoss3.2以后的版本中,定义了"ProxyFamily"术语。isdefined.AProxyFamilyisasetofstubinterceptorsthatallmakeinvocationsagainstthesamereplicatedtarget.ForEJBsforexample,allstubstargetingthesameEJBinagivenclusterbelongtothesameproxyfamily.Allinterceptorsofagivenfamilysharethesamelistoftargetnodes.Eachinterceptoralsohastheabilitytosharearbitraryinformationwithotherinterceptorsofthesamefamily.AusecasefortheproxyfamilyisgiveinSection1.3.1,“StatelessSessionBeaninEJB2.x”.

1.2.4布署

在一个集群中布署应用程序最容易的方式是使用farming服务,就是将一个应用程序压缩文件(EAR,WAR或SAR)热布署到任一个节点的all/farm/目录,应用程序会自动地复制到集群中的其他节点。如果稍后有新的节点加入,新节点启动时也会自动从集群中复制应用程序并布署到本地。在集群运行的过程中,如果从任一节点的farm目录移除应用程序,这个应用程序将首先从本地卸载,然后再从集群的其他节点中卸载。应该手动从当前没有连接到集群的服务器节点中删除应用程序。

注意

当前存在一个Bug,Farm布署服务只能在热布署压缩文件的方式中才能生效。如果你首先放一个应用程序在farm目录,然后启动服务器,这个应用程序将不会被检测并布署到集群中。

注意

在farm目录中只能使用压缩文件,而不能使用展开的目录。

Farming服务在JBossAS发布版的all配置集中是缺省启用的,不需要手动设置。配置文件保存在deploy/deploy.last目录,如果需要在集群配置中启用farming服务,创建farm-service.xml文件如下,并拷贝到JBoss布署目录$JBOSS_HOME/server/your_own_config/deploy,确保在配置中已经启用集群服务。

xml代码

<!--sp-->xmlversion="1.0"encoding="UTF-8"?>

<server>

<mbeancode="org.jboss.ha.framework.server.FarmMemberService"

name="jboss:service=FarmMember,partition=DefaultPartition">

...

<attributename="PartitionName">DefaultPartitionattribute>

<attributename="ScanPeriod">5000attribute>

<attributename="URLs">farm/attribute>

mbean>

server>

FarmMemberServiceMBean可用的属性如下:

PartitionName指定集群名字,缺省值为DefaultPartition.

URLs指定布署器监控布署文件的目录,如果不存在,MBean将创建。"."表示配置目录(比如$JBOSS_HOME/server/all/)。

ScanPeriod指定文件夹的扫描周期,缺省值为5000。

Farming服务是URLDeploymentScanner的扩展,用来扫描deploy目录,因此在FarmMemberServiceMBean中可以使用URLDeploymentScannerMBean中定义的所有属性。

1.2.4分布式状态复制服务

集群环境中,分布式状态管理是集群必须提供的一个关键服务。比如一个有状态的会话Bean应用程序,会话状态必须在所有节点的Bean实例中保持同步,因此不管哪个节点服务请求,客户端应该得到同样的会话状态。实体Bean应用程序中,Bean实例必须在集群中进行缓存以减轻数据库负载。目前JBossAS中的状态复制和分布式缓存由两种方式提供:HASessionStateMBean和JBossCache框架。

HASessionStateMBean基于EJB2.X有状态会话Bean和JBoss3.x和4.x的HTTP负载平衡器提供会话复制和分布式缓存服务。MBean相关定义在all/deploy/cluster-service.xml文件中。

JBossCache是一个分布式缓存框架,可以用在任何应用程序服务器环境,也可以独立使用,已经逐渐替换HASessionState服务。JBossAS整合JBossCache为HTTP会话,EJB3.0会话和实体Bean,Hibernate持久对象提供缓存服务。这些缓存服务都在独立的MBean中定义。

1.5HTTP服务

HTTP会话复制用来在你的WEB客户端和集群的节点之间复制状态,那么当某一个节点崩溃时,集群中的其他节点可以恢复。要实现这个目的,必须执行两个步骤:

会话状态复制

请求负载平衡

如果使用all配置集启动JBoss,缺省会启用会话状态复制功能,只需要布署你的应用程序,会话状态就已经可以在集群中进行复制。

但是负载平衡需要额外的软件支持,作为一个常用的场景,我们将描述如何设置Apache和mod_jk。这个功能也可以通过专门的硬件或者其他软件来实现。

注意

一个负载平衡器跟踪HTTP请求,根据和请求关联的会话,决定派发请求到合适的节点。这被称作使用sticky-sessions的负载平衡器:一旦在某个节点创建了会话,随后的请求将由同一个节点进行处理。使用一个支持sticky-sessions的负载平衡器可以不用复制会话,没有会话状态复制的花销,每个请求将是被同一个节点处理。但是一旦这个节点崩溃,保存在这个节点的所有客户会话都将丢失,客户必须登录进另一个节点,重新启动一个新的会话。在某些情况,不复制HTTP会话是可以接受的,因为比较关键的状态都保存在数据库中,但是也有些情况下,丢失会话状态是无法接受的,这种情况下,会话状态复制的花销是必须承受的。

Apache是一个可以通过插入模块扩展功能的WEB服务器,mod_jk(最新的mod_jk2)模块的主要功能就是允许从Apache分发请求到一个Servlet容器,还可以支持在多个Servlet容器中负载平衡HTTP调用(遵循sticky-sessions)。

1.5.1.下载软件

http://httpd.apache.org/下载Apache,安装是非常直白的,不需要特别的配置,推荐使用2.0.x版本,这里假定Apache安装目录为APACHE_HOME。

然后从www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/.下载mod_jk模块,建议使用mod_jk1.2.x版本。重命名下载的文件为mod_jk.so,拷贝到APACHE_HOME/modules/目录下。

1.5.2.配置Apache使用mod_jk

更改APACHE_HOME/conf/httpd.conf文件,在文件尾部添加一行:

java代码

#Includemod_jk'sspecificconfigurationfile

Includeconf/mod-jk.conf

创建文件APACHE_HOME/conf/mod-jk.conf:

java代码#Loadmod_jkmodule
#Specifythefilenameofthemod_jklib
LoadModulejk_modulemodules/mod_jk.so

#Wheretofindworkers.properties
JkWorkersFileconf/workers.properties

#Wheretoputjklogs
JkLogFilelogs/mod_jk.log

#Setthejkloglevel[debug/error/info]
JkLogLevelinfo

#Selectthelogformat
JkLogStampFormat"[%a%b%d%H:%M:%S%Y]"

#JkOptionsindicatestosendSSKKEYSIZE
JkOptions+ForwardKeySize+ForwardURICompat-ForwardDirectories

#JkRequestLogFormat
JkRequestLogFormat"%w%V%T"

#Mountyourapplications
JkMount/application/*loadbalancer

#Youcanuseexternalfileformountpoints.
#Itwillbecheckedforupdateseach60seconds.
#Theformatofthefileis:/url=worker
#/examples/*=loadbalancer
JkMountFileconf/uriworkermap.properties

#Addsharedmemory.
#Thisdirectiveispresentwith1.2.10and
#laterversionsofmod_jk,andisneededfor
#forloadbalancingtoworkproperly
JkShmFilelogs/jk.shm

#Addjkstatusformanagingruntimedata

JkMountstatus
Orderdeny,allow
Denyfromall
Allowfrom127.0.0.1

其中有两个设置是非常重要的:

LoadModule指令必须引用下载的mod_jk库,路径中必须包括modules前缀。

JkMount指令通知Apache哪些URL应该被派发给mod_jk模块(也就是派发给Servlet容器)。上面的配置中,所有基于/application/*的请求都会派发给mod_jk负载平衡器。如果使用mod_jk作为一个专门的负载平衡器,可以将所有的请求(/*)派发给mod_jk。

除了使用JkMount指令,也可以使用JkMountFile指令指定一个配置文件,包含多个URL映射配置。你只需要在APACHE_HOME/conf目录下创建一个uriworkermap.properties文件。文件格式为/url=worker_name,示例文件如下:

java代码#Simpleworkerconfigurationfile

#MounttheServletcontexttotheajp13worker
/jmx-console=loadbalancer
/jmx-console/*=loadbalancer
/web-console=loadbalancer
/web-console/*=loadbalancer

如上示例将配置mod_jk派发请求/jmx-console和/web-console给Tomcat。

1.5.3.在mod_jk中配置工作者节点

接着需要创建conf/workers.properties文件,这个文件用来指定名个不同的Servlet容器的位置以及调用如何在这些容器之间进行平衡。针对一个两个节点的设置,示例文件如下:

java代码#Definelistofworkersthatwillbeused
#formappingrequests
worker.list=loadbalancer,status

#DefineNode1
#modifythehostasyourhostIPorDNSname.
worker.node1.port=8009
worker.node1.host=node1.mydomain.com
worker.node1.type=ajp13
worker.node1.lbfactor=1
worker.node1.cachesize=10

#DefineNode2
#modifythehostasyourhostIPorDNSname.
worker.node2.port=8009
worker.node2.host=node2.mydomain.com
worker.node2.type=ajp13
worker.node2.lbfactor=1
worker.node2.cachesize=10

#Load-balancingbehaviour
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=1
#worker.list=loadbalancer

#Statusworkerformanagingloadbalancer
worker.status.type=status

上述文件配置mod_jk执行Round-Robin的基于sticky-sessions的负载平衡策略,两个节点都监听8009端口。

works.properties文件中,每个节点使用worker.XXX命名规范进行定义,这里XXX可以是任何名字,用来命名Servlet容器。对于每个工作者,必须指定在目标Servlet容器中配置的AJP13连接器的IP地址和端口号。

lbfactor属性用来表示负载平衡权重,决定节点之间的优先级,值越大,该节点将接受越多的请求。这个选项可以用来分配不同的节点不同的负载。

cachesize属性定义关联的Servlet容器的线程池大小,确定这个值没有超过Servlet容器在AJP13连接器中的配置。可以参考jakarta.apache.org/tomcat/connectors-doc/config/workers.html

conf/workers.properties最后定义负载平衡工作者,唯一需要改变的是worker.loadbalancer.balanced_workers设置,必须列出刚才定义的所有工作者。

sticky_session属性指定集群针对HTTP会话的处理方式,如果指定worker.loadbalancer.sticky_session=0,每个请求将在两个节点中进行负载平衡。但是当一个用户在某个节点创建一个会话时,比较好的方式是随后的请求都导向这个节点,这被称作"stickysession",由于客户总是使用会话创建的节点服务所有随后的请求。否则用户的会话数据必须在两个节点进行同步,要启用"stickysession",必须设置worker.loadbalancer.sticky_session值为1。

注意

Anon-loadbalancedsetupwithasinglenoderequiredtheworker.list=node1entrybeforemod_jkwouldfunctioncorrectly.

1.5.4.配置JBoss

最后必须配置集群中所有节点的JBossTomcat实例。

在每个节点中,我们必须根据workers.properties文件中的worker名称来命名节点。比如,在JBoss实例node1中,需要编辑JBOSS_HOME/server/all/deploy/jbossweb-tomcat50.sar/server.xml文件,定位元素添加一个jvmRoute属性:

xml代码

<Enginename="jboss.web"defaultHost="localhost"jvmRoute="node1">

......

Engine>

然后,对于集群中的每一个节点,我们必须通知它添加一个jvmRoute值到会话cookies中,以便mod_jk可以路由随后的请求。编辑JBOSS_HOME/server/all/deploy/jbossweb-tomcat50.sar/META-INF/jboss-service.xml文件,定义UseJK的元素,设置值为true:

xml代码

<attributename="UseJK">trueattribute>

到此为止,我们已经成功设置Apache_mod_jk使用sticky-session方式的负载平衡。

注意

更多信息可以参考http://wiki.jboss.org/wiki/Wiki.jsp?page=UsingMod_jk1.2WithJBoss。

1.5.5.配置HTTP会话状态复制

目前为止,已经成功配置了sticky-session方式的负载平衡,但是这种方式并不是一个完善的解决方案,因为一个节点崩溃,所有的会话数据都会丢失。更可选的解决方式是在集群的节点之间复制会话状态,这样客户访问任一个节点都会获得同样的会话状态。

jboss.cache:service=TomcatClusteringCacheMBean使用JBossCache提供HTTP会话状态复制服务,这个MBean定义在deploy/tc5-cluster.sar/META-INF/jboss-service.xml文件中。

注意

JBossAS4.0.4CR2以前的版本,HTTP会话缓存配置文件在deploy/tc5-cluster-service.xml文件中。

下面是一个典型的deploy/tc5-cluster.sar/META-INF/jboss-service.xml文件

xml代码

<mbeancode="org.jboss.cache.aop.TreeCacheAop"

name="jboss.cache:service=TomcatClusteringCache">

<depends>jboss:service=Namingdepends>

<depends>jboss:service=TransactionManagerdepends>

<depends>jboss.aop:service=AspectDeployerdepends>

<attributename="TransactionManagerLookupClass">

org.jboss.cache.BatchModeTransactionManagerLookup

attribute>

<attributename="IsolationLevel">REPEATABLE_READattribute>

<attributename="CacheMode">REPL_ASYNCattribute>

<attributename="ClusterName">

Tomcat-${jboss.partition.name:Cluster}

attribute>

<attributename="UseMarshalling">falseattribute>

<attributename="InactiveOnStartup">falseattribute>

<attributename="ClusterConfig">

......

attribute>

<attributename="LockAcquisitionTimeout">15000attribute>

mbean>

详细的配置请参见JBossCache缓存配置部分,下面讨论几个比较关键的配置:

TransactionManagerLookupClass设置事务管理器工厂,缺省值为org.jboss.cache.BatchModeTransactionManagerLookup,这个类通知缓存不要参与JTA事务,自己管理事务。

IsolationLevel设置更新分布式缓存的隔离级别,可选值包括:SERIALIZABLE,REPEATABLE_READ,READ_COMMITTED,READ_UNCOMMITTED,和NONE。这里的隔离级别和数据库的隔离级别有同样的含义,对于大多数WEB应用程序来讲通常设置为REPEATABLE_READ。

CacheMode控制缓存如何被复制。可选值包括:REPL_SYNC和REPL_ASYNC,确定改变是应该同步还是异步复制。使用同步复制,确保在请求完成之前传播改变,同步复制相对来说会慢一些。

ClusterName指定集群名称。缺省的集群名称是由当前的JBoss分区名称加上"Tomcat-"前缀。所有的节点应该使用相同的集群名称。

UseMarshallingInactiveOnStartup属性必须有相同的值,如果使用FIELD级别的会话复制,这两个值必须为true。

ClusterConfig配置底层的JGoups堆栈。最重要的配置元素是广播地址和端口号mcast_addr和mcast_port,详细配置请参见JGroups配置。

LockAcquisitionTimeout设置获取锁的最大超时值,缺省值为15000。

UseReplQueue使用异步复制时是否启动复制队列,这允许多个更新一起执行从而提升性能。复制队列属性由ReplQueueInterval和ReplQueueMaxElements属性配置。

ReplQueueInterval配置JBoss缓存处理复制队列的时间间隔。

ReplQueueMaxElements:配置复制队列可以保存的最多的元素数目。

1.5.6.在应用程序中启用会话复制

要在你的WEB应用程序中启用集群,必须在web.xml文件中声明distributable。示例如下:

xml代码

<!--sp-->xmlversion="1.0"?>

<web-appxmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">

<distributable/>

<!--...-->

web-app>

<!--lversion="1.0-->
可以在jboss-web.xml文件中进一步配置会话复制,示例如下:

xml代码<jboss-web>
<replication-config>
<replication-trigger>SET_AND_NON_PRIMITIVE_GETreplication-trigger>
<replication-granularity>SESSIONreplication-granularity>
<replication-field-batch-mode>truereplication-field-batch-mode>
replication-config>
jboss-web>

replication-trigger元素确定什么情况触发一次会话复制,有四个选项:

SET:使用此选项,一个会话只有在设置属性时才被认为需要复制。如果你的应用总是需要改变会话的属性,这个选项将是性能最优的。如果一个对象只是被检索和修改,但是不需要改写会话,这个对象的改变并不会造成会话复制。

SET_AND_GET:使用此选项,任何属性的获取和设置都被认为需要复制。如果一个对象被检索和修改,但是不需要改定会话,这个对象的改变将会被复制。这个选项有显著的性能问题。

SET_AND_NON_PRIMITIVE_GET:此选项类似于SET_AND_GET,唯一的例外是只有非原始类型的检索操作被认为需要复制。比如,HTTP会话请求可以从属性中检索一个非原始类型的对象实例并更改,如果我们没有指定此选项,更改将不会被复制。这是缺省设置。

ACCESS:使用此选项,只要会话被访问都被认为需要复制。由于每个HTTP请求都会造成会话被访问,所以每个请求都会导致会话复制。使用此选项,会话时间戳将在集群中同步。注意使用此选项会有显著的性能问题。

replication-granularity元素控制复制粒度,支持的选项包括:

SESSION:基于会话的复制,只要会话发生改变,整个会话对象都会被序列化。

ATTRIBUTE:基于属性的复制,复制只在属性被认为是脏的时候发生,比如lastAccessTime.。对于持有大量数据的会话,这个选项可以提升性能。

FIELD:基于字段的复制,复制只在会话属性包含的对象的字段发生变化时发生。

replication-field-batch-mode表示是否需要在每个HTTP请求进行批量更新,缺省值为true。

如果你的会话通常比较小,SESSION选项比较适合,如果会话比较大,而且某些部分不是经常被访问,ATTRIBUTE选项比较适合,如果会话属性包含大数据量的对象而且只有字段经常更改,FIELD选项比较适合。

1.5.7.使用FIELD级别的复制

FIELD-levelreplicationonlyreplicatesmodifieddatafieldsinsideobjectsstoredinthesession.Itcouldpotentiallydrasticallyreducethedatatrafficbetweenclusterednodes,andhenceimprovetheperformanceofthewholecluster.TouseFIELD-levelreplication,youhavetofirstprepareyourJavaclasstoindicatewhichfieldsaretobereplicated.ThisisdoneviaJDK1.4styleannotationsembeddedinJavaDocs:

ToannotateyourPOJO,weprovidetwoannotations:@@org.jboss.web.tomcat.tc5.session.AopMarkerand@@org.jboss.web.tomcat.tc5.session.InstanceAopMarker.WhenyouannotateyourclasswithAopMarker,youindicatethatinstancesofthisclasswillbeusedinFIELD-levelreplication.Forexmaple,

/*
*Myusualcommentsherefirst.
*@@org.jboss.web.tomcat.tc5.session.AopMarker
*/
publicclassAddress
{
...
}

IfyouannotateitwithInstanceAopMarkerinstead,thenallofitssub-classwillbeautomaticallyannotatedaswell.Forexample,

/*
*
*@@org.jboss.web.tomcat.tc5.session.InstanceOfAopMarker
*/
publicclassPerson
{
...
}

thenwhenyouhaveasub-classlike

publicclassStudentextendsPerson
{
...
}

therewillbenoneedtoannotateStudent.Itwillbeannotatedautomaticallybecauseitisasub-classofPerson.

However,sinceweonlysupportJDK1.4styleannotation(providedbyJBossAop)now,youwillneedtoperformapre-processingstep.YouneedtousetheJBossAOPpre-compilerannotationcandpost-compileraopctoprocesstheabovesourcecodebeforeandaftertheyarecompiledbytheJavacompiler.Hereisanexampleonhowtoinvokethosecommandsfromcommandline.

$annotationc[classpath][sourcefilesordirectories]
$javac-cp[classpath][sourcefilesordirectories]
$aopc[classpath][classfilesordirectories]

PleaseseetheJBossAOPdocumentationfortheusageofthepre-andpost-compiler.TheJBossAOPprojectalsoprovideseasytouseANTtaskstohelpintegratethosestepsintoyourapplicationbuildprocess.InthenextASrelease,JDK5.0annotationsupportwillbeprovidedforgreatertransparency.Butfornow,itisimportantthatyouperformthepre-andpost-compilationstepsforyoursourcecode.

Note

Or,youcanseeacompleteexampleonhowtobuild,deploy,andvalidateaFIELD-levelreplicatedwebapplicationfromthispage:http://wiki.jboss.org/wiki/Wiki.jsp?page=Http_session_field_level_example.Theexamplebundlesthepre-andpost-compiletoolssoyoudonotneedtodownloadJBossAOPseparately.

WhenyoudeploythewebapplicationintoJBossAS,makesurethatthefollowingconfigurationsarecorrect:

Intheserver'sdeploy/tc5-cluster.sar/META-INF/jboss-service.xmlfile,theinactiveOnStartupanduseMarshallingattributesmustbothbetrue.

Intheapplication'sjboss-web.xmlfile,thereplication-granularityattributemustbeFIELD.

Finally,let'sseeanexampleonhowtouseFIELD-levelreplicationonthosedataclasses.Noticethatthereisnoneedtocallsession.setAttribute()afteryoumakechangestothedataobject,andallchangestothefieldsareautomaticallyreplicatedacrossthecluster.


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: