一、JBOSS集群介绍
Jboss 支持如下类型的cluster:EJB、HTTP、JNDI、JMS,本文主要了解HTTP cluster。JBOSS的HTTP cluster实现了两项任务:会话状态复制(Session state replication)与负载平衡(Load-balance of incoming invocations)。
会话状态复制用来复制集群中不同节点上客户端的连接状态,以实现当集群中的某一节点发生故障时,集群中的其它节点能够接管连接到故障节点的客户端请求,接管过程对客户端透明,客户端并不知道是否发生了服务提供者的转移。会话状态复制由JBOSS本身进行控制,当JBOSS以all的配置方式运行时,默认已经启动了会话状态复制。
负载均衡顾名思义,就是希望集群中的节点均衡的提供服务,以防止某一节点负载过重,导致连接到该节点的请求不能在期望的时间内完成,而其它的节点又存在大量的空闲资源。负载均衡并不由JBOSS本身控制,它需要额外的软件或硬件交换机或路由器进行负载均衡控制。本文是通过Apache与mod_jk进行负载均衡配置。负载均衡可以选择针对每个请求的均衡,或者是针对每个用户的均衡。选择不同的粒度,需要不同的状态同步方式。
1、基于请求的负载均衡
该种方式下,负载均衡器 (load balancer)会根据各个node的状况,把每个http request进行分发。使用这样的均衡策略,就必须在多个node之间复制用户的session,实时保持整个cluster的用户状态同步,这种操作被称为session复制 (session replication)。Jboss的实现原理是使用拦截器(interceptor),根据用户的同步策略拦截request,做同步处理后再交给server产生响应。
该方法的优点是客户不会被绑定都具体的node,只要还有一个node存活,用户状态都不会丢失,cluster都能够继续工作。缺点是node之间通信频繁,响应速度有影响,多并发、高频操作的情况下性能下降比较厉害。
2、基于用户的负载均衡
该种方式下,当用户发出第一个request后,负载均衡器动态的把该用户分配到某个节点,并记录该节点的jvm路由,以后该用户的所有request都会被绑定这个jvm路由,用户只会与该server发生交互,这种策略被称为粘性session(sticky-session)。
该方法的优点是响应速度快,多个节点之间无须通信。缺点也很明显,某个node死掉以后,它负责的所有用户都会丢失session。
二、下载并安装软件
1. JDK1.5:在集群的每个节点上安装JDK并设置JAVA_HOME环境变量
2. JBOSS 4.0.2:在集群的每个节点上,把下载的压缩文件解压到合适的目录
3. Apache 2.0.47:在负载分发节点上安装Apache,建议不要用集群中的节点做负载分发器,Apache的版本并不要求严格一致。
4. mod_jk-apache-2.0.55.so:建议下载mod_jk1.2.x版本,其它版本没有提供支持,可在 处下载,下载之后将mod_jk-apache-2.0.55.so改名为mod_jk.so,将该文件复制到APACHE_HOME/modules/目录下
三、负载均衡分发节点即mod-jk的配置
1. 配置Apache装载mod_jk
Øa)修改APACHE_HOME/conf/httpd.conf ,在该文件的末尾增加下面的命令:
# Include mod_jk's specific configuration file
Include conf/mod-jk.conf
Øb)创建文件APACHE_HOME/conf/mod-jk.conf,内容如下:
# Load mod_jk module
# Specify the filename of the mod_jk lib
LoadModule jk_module modules/mod_jk.so
# Where to find workers.properties
JkWorkersFile conf/workers.properties
# Where to put jk logs
JkLogFile logs/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel info
# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
# JkOptions indicates to send SSK KEY SIZE
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat
JkRequestLogFormat "%w %V %T"
# Mount your applications
JkMount /application/* loadbalancer
# You can use external file for mount points.
# It will be checked for updates each 60 seconds.
# The format of the file is: /url=worker
# /examples/*=loadbalancer
JkMountFile conf/uriworkermap.properties
# Add shared memory.
# This directive is present with 1.2.10 and
# later versions of mod_jk, and is needed for
# for load balancing to work properly
JkShmFile logs/jk.shm
# Add jkstatus for managing runtime data
JkMount status
Order deny,allow
Deny from all
Allow from 127.0.0.1
:
该文件中,有两处设置比较重要:LoadModule与JkMount。LoadModule中要正确设置mod_jk的路径;JkMount指明Apache需要将哪些url进行转发,在上面 的设置中,Apache将会把url路径为 /application/* 的请求发送到mod_jk负载均衡。通过该方式,可以配置Apache提供静态Web页面服务,并把动态页面功能转发到JBOSS服务器。如果希望所有的服务都由JBOSS集群服务提供,则把JKMount设置为JkMount /* loadbalancer即可。
除了通过JKMount设置转发路径外,你可以通过JkMountFile详细设置哪些url需要通过mod_jk进行负载均衡转发。通过在APACHE_HOME/conf目录下创建文件uriworkermap.properties进行控制,文件格式为/url=worker_name,可以通过下面的例子进行说明:
# Simple worker configuration file
# Mount the Servlet context to the ajp13 worker
/jmx-console=loadbalancer
/jmx-console/*=loadbalancer
/web-console=loadbalancer
/web-console/*=loadbalancer
上面是文件uriworkermap.properties的示例内容,该配置表明mod_jk负载平衡将把/jmx-console和/web-console请求转发给JBOSS集群服务器。2.配置mod_jk中的集群工作节点
创建文件conf/workers.properties,内容如下:
# Define list of workers that will be used
# for mapping requests
worker.list=loadbalancer,status
# Define Node1
# modify the host as your host IP or DNS name.
worker.node1.port=8009
worker.node1.host=172.16.11.206
worker.node1.type=ajp13
worker.node1.lbfactor=1
worker.node1.cachesize=10
# Define Node2
# modify the host as your host IP or DNS name.
worker.node2.port=8009
worker.node2.host= 172.16.11.207
worker.node2.type=ajp13
worker.node2.lbfactor=1
worker.node2.cachesize=10
# Load-balancing behaviour
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=1
#worker.list=loadbalancer
# Status worker for managing load balancer
worker.status.type=status
该文件详细定义了负载均衡将要转发到的目标节点。其中对于节点的命名规则是worker.节点名.xxxx。所以上述文件定义了两个节点:node1和node2。8009端口是jboss默认的ajp端口,另外需要注意的是 worker.节点名.lbfactor 参数,它是节点的负载加权,它的值越大,获得负载的机会就越大。可以根据node的硬件性能进行调整。worker.loadbalancer.balance_workers列出所有转发的目标节点,即JBOSS HTTP集群的所有节点, worker.loadbalancer.sticky_session 参数是指定是否使用粘性session,当设置为0时,是基于请求的负载均衡,为1时是基于用户的负载均衡。
四、JBOSS服务器配置
为了使JBOSS集群中的每个节点能够接受mod_jk转发来的请求,需要在每个节点上配置jvm,步骤如下:
1. 编辑文件JBOSS_HOME/server/all/deploy/jbossweb-tomcat50.sar/server.xml,找到元素,增加jvmRoute属性,如下:
其中jvmRoute的值要与在Apache中workers.properties定义的名称一致
2. 编辑JBOSS_HOME/server/all/deploy/jbossweb-tomcat50.sar/META-INF/jboss-service.xml,找到name为UseJK的
元素,将其值设置为True,如下:
五、配置HTTP session state replication
jboss.cache:service=TomcatClusteringCache Mbean利用Jboss Cache提供Jboss Tomcat集群中的HTTP会话复制服务,该Mbean定义在JBOSS_HOME/server/all/deploy/ tc5-cluster-service.xml文件中,如果是Jboss在all配置下运行,默认启动了HTTP会话复制服务,不需要进行额外配置。如果是运行在自定义的配置下,同时要实现HTTP会话复制,则需要将文件deploy/tc5-cluster-service.xml, lib/jgroups.jar 和 lib/jboss-cache.jar从server/all目录复制到自定义的配置目录下。
一个典型的tc5-cluster-service.xml文件所包含的内容如下:
name="jboss.cache:service=TomcatClusteringCache">
jboss:service=Naming
jboss:service=TransactionManager
org.jboss.cache.JBossTransactionManagerLookup
... ...
下面简要说明跟HTTP集群会话复制相关的几个属性:
Ø TransactionManagerLookupClass sets the transaction manager factory. The default value is org.jboss.cache.JBossTransactionManagerLookup. It expects to find the transaction manager under java:/TransactionManager.
Ø IsolationLevel sets the isolation level for updates to the transactional distributed cache. The valid values are SERIALIZABLE, REPEATABLE_READ, READ_COMMITTED, READ_UNCOMMITTED, and NONE. These isolation levels mean the same thing as isolation levels on the database. The default isolation of REPEATABLE_READ makes sense for most web applications.
Ø CacheMode controls how the cache is replicated. The valid values are REPL_SYNC and REPL_ASYNC, which determine whether changes are made synchronously or asynchronously. Using synchronous replication makes sure changes propagated to the cluster before the web request completes. However, synchronous replication is much slower. For asyncrhonous access, you will want to enable and tune the replication queue.
Ø ClusterName specifies the name of the cluster that the cache works within. The default cluster name is Tomcat-Cluster. All the nodes should use the same cluster name. Although session replication can share the same channel (multicast address and port) with other clustered services in JBoss, replication should have it's own cluster name.
Ø ClusterConfig configures the underlying JGroups stack. The most import configuration elements are the muliticast adress and port, mcast_addr and mcast_port respectively, to use for clustered communication. These values should make sense for your network.
Ø LockAcquisitionTimeout sets the maximum number of milliseconds to wait for a lock acquisition. The default value is 15000.
Ø UseReplQueue determines whether to enable the replication queue when using asynchronous replication. This allows multiple cache updates to be bundled together to improve performance. The replication queue properties are controlled by the ReplQueueInterval and ReplQueueMaxElements properties.
Ø ReplQueueInterval specifies the time in milliseconds JBoss Cache will wait before sending items in the replication queue.
Ø ReplQueueMaxElements: specifies the maximum number of elements allowed in the replication queue before JBoss Cache will send an update.
六、测试集群配置是否成功
做了以上步骤之后,Jboss HTTP集群配置基本完成,可以通过下列方式验证:在安装Apache的机器上启动Apache服务,在Jboss的集群节点上启动Jboss服务,可以通过运行JBOSS_HOME/bin目录下的run命令启动,为了简单起见,我们直接运行all配置,可以通过运行JBOSS_HOME/bin/run -c all命令实现。
服务启动之后,在Apache服务器上运行,则Apache服务器的默认页面打开;在Apache服务器上运行 时,则打开了Jboss服务器的jmx-console,再次打开一IE输入 时,则该请求由Jboss集群服务器中的另一个节点来服务,如果在其它的机器上测试,则上面的localhost改为Apache服务器的IP地址或者DNS名称
由于我们在mod-jk的配置文件中设置JkMount的值与uriworkermap.properties文件的值均不包含根目录,也即mod-jk只负责转发JkMount的值与uriworkermap.properties文件的值所定义的url,没有定义的url则由Apache服务本身来提供响应。如果把JkMount设置为:JkMount /* loadbalancer,执行 请求,则返回Jboss集群中HTTP的默认页面.
当循环打开IE执行 请求时,根据返回的请求,可以看出,该请求由Jboss HTTP集群中的节点node1、node2轮流提供服务。
当通过运行Apache的测试程序ab时,可以看出2节点的Jboss HTTP集群提供的服务与单个Jboss服务器提供服务有明显的性能差异。分别用的测试命令
ab -n 500 -c 20
ab -n 500 -c 20
测试单节点服务器与2节点集群服务器的性能,由测试结果可以看出在同样的负载请求下,2节点的集群98%的请求在15ms内完成,单节点的服务器只有80%的请求在15ms内完成。
七、配置自己的Web应用支持集群
为了使自己的Web应用支持集群,需要在在自己的Web应用的配置文件进行设置,让它支持集群,在web.xml文件中加入属性,示例如下:
xmlns:xsi=""
xsi:schemaLocation="
/web-app_2_4.xsd"
version="2.4">
为了使自己的Web应用能够实现会话状态复制,需要配置自己的web应用的jboss-web.xml文件,在jboss-web.xml中加入replication-config元素,示例如下:
SET_AND_NON_PRIMITIVE_GET
SESSION
其中replication-trigger元素设定什么时候触发会话复制,有四个选项:
Ø SET: With this policy, the session is considered dirty only when an attribute is set in the session. If your application always writes changed value back into the session, this option will be most optimized in term of performance.If an object is retrieved from the session and modified without being written back into the session, the change to that object will not be replicated.
Ø SET_AND_GET: With this policy, any attribute that is get or set will be marked as dirty. If an object is retrieved from the session and modified without being written back into the session, the change to that object will be replicated. This option can have significant performance implications.
Ø SET_AND_NON_PRIMITIVE_GET: This policy is similar to the SET_AND_GET policy except that only non-primitive get operations are considered dirty. For example, the http session request may retrieve a nonprimitive object instance from the attribute and then modify the instance. If we don't specify that non-primitive get is considered dirty, then the modification will not be replication properly. This is the default value.
Ø ACCESS: This option causes the session to be marked as dirty whenever it is accessed. Since a the session is accessed during each HTTP request, it will be replicated with each request. The access time stamp in the session instance will be updated as well. Since the time stamp may not be updated in other clustering nodes because of no replication, the session in other nodes may expire before the active node if the HTTP request does not retrieve or modify any session attributes. When this option is set, the session timestamps will be synchronized throughout the cluster nodes. Note that use of this option can have a significant performance impact, so use it with caution.
replication-granularity元素用来控制复制单位,有两个选项:
Ø session: Replication is per session instance. As long as it is considered modified when the snapshot manager is called, the whole session object will be serialized.
attribute: Replication is only for the dirty attributes plus some session data, like, lastAccessTime. For session that carries large amount of data, this option can increase replication performance.If your sessions are generally small, session is the better policy. If your session is larger and some partsare infrequently accessed, attribute replication will be more effective.
八、查看会话复制
在部署并访问了自己的Web集群应用之后,可以通过调用jboss.cache:service=TomcatClusteringCache Mbean的printDetails操作,来查看会话复制状况。通过访问,在该页面中点击jboss.cache:service=TomcatClusteringCache后在打开的页面中调用printDetails()操作)
当调用了printDetails()操作之后,将会显示类似如下内容的页面:
/JSESSION
/quote
/FB04767C454BAB3B2E462A27CB571330
VERSION: 6
FB04767C454BAB3B2E462A27CB571330: org.jboss.invocation.MarshalledValue@1f13a81c
/AxCI8Ovt5VQTfNyYy9Bomw**
VERSION: 4
AxCI8Ovt5VQTfNyYy9Bomw**: org.jboss.invocation.MarshalledValue@e076e4c8
上面示例的显示结果表明有两个独立的web sessions,其中一个应用名为quote,sessions通过Jboss-Cache共享,在该应用中,复制的粒度为session而不是attribute.
九、集群热部署
在一个节点很多的cluster中,如果部署应用的时候必须把程序文件拷贝到每个机器上的话,那实在太麻烦了,通过all启动的jboss自动支持分布式热部署。把支持cluster的应用(通常需要打包成war文件),放到JBOSS_HOME/server/all/farm下,那么处于同一 cluster中的其他节点会自动下载并且部署,Jboss把这个称为Farm deploy