﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-　　　　　　　　　　　　　彬 ^_^ -文章分类-JBoss</title><link>http://www.blogjava.net/libin2722/category/32629.html</link><description>虚其心，可解天下之问；专其心，可治天下之学；静其心，可悟天下之理；恒其心，可成天下之业。</description><language>zh-cn</language><lastBuildDate>Wed, 20 May 2009 10:59:24 GMT</lastBuildDate><pubDate>Wed, 20 May 2009 10:59:24 GMT</pubDate><ttl>60</ttl><item><title>SC 创建.删除 Windows Service</title><link>http://www.blogjava.net/libin2722/articles/268951.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Tue, 05 May 2009 05:02:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/268951.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/268951.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/268951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/268951.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/268951.html</trackback:ping><description><![CDATA[
		<p>创建服务: sc create "Jboss for Adobe LiveCycle" binPath=
"C:\Adobe\LiveCycle\jboss\jbossService.exe" displayName= "Jboss for
Adobe LiveCyele" </p>
		<p>删除服务: sc delete "Jboss for Adobe LiveCycle"<br /> </p>
		<p>在创建服务的时候, 开始老是不成功, 后来发现是在参数 "binPath=" 后面和 "displayName="后面,都是要有一个空格的......<img alt="" src="http://blog.csdn.net/fckeditor/editor/images/smiley/msn/confused_smile.gif" /> ..好奇怪呀. .</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/268951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-05-05 13:02 <a href="http://www.blogjava.net/libin2722/articles/268951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat下绑定JMS应用服务器的实例讲解</title><link>http://www.blogjava.net/libin2722/articles/249367.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Wed, 31 Dec 2008 10:07:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/249367.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/249367.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/249367.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/249367.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/249367.html</trackback:ping><description><![CDATA[<p><span id="zoom">
<p>JMS做为J2EE的高级部分一直蒙着一层神秘的面纱，作为JMS的定制者SUN只规定了JMS规范，象很多其他SUN产品一样被多家厂商提供了具
体的实现。但是作为tomcat和RESIN（今年初宣布全部支持J2EE规范）。这些面向低端但却被广泛应用的服务器本身并不对JMS提供支持。庆幸的
是openjms和activeMQ两家开源软件提供了插件式的支持。 </p>
<p>在应用了一些开发框架如spring的项目里如果要使用到JMS，虽然SPRING提供了部分对JMS的支持但经过我一段时间的应用发
现，OO的封装在某些地方反而成为开发过程中的障碍。在实现诸如监听之类的代码段里使人非常的懊恼，即使用callback(回调)有些东西仍然不能够很
好的被取到。 </p>
<p>下面就一些TOMCAT上面JMS的支持既实现做一下整理。
</p>
<p>1.很自然的你需要下载JMS实现,如:opnerJMS或者activeMQ .下载地址www.jmsopen.com 或www.activeMQ.com
</p>
<p>2.服务器下载以后的具体配置在以上两个网站上都有很详细的说明，就不再列举了。
</p>
<p>3.和WEB服务器的整合，首先要配置应用的web.xml这个文件配置如下：
</p>
<center><ccid_nobr>
<table bordercolordark="#ffffff" bordercolorlight="black" align="center" border="1" cellpadding="2" cellspacing="0" width="400">
    <tbody>
        <tr>
            <td style="font-size: 9pt;" bgcolor="#e6e6e6">
            <pre><ccid_code>1  &lt;context-param&gt;<br />
            2  &lt;param-name&gt;brokerURI&lt;/param-name&gt;<br />
            3  &lt;param-value&gt;/WEB-INF/activemq.xml&lt;/param-value&gt;<br />
            4  &lt;/context-param&gt;<br />
            5<br />
            6  &lt;listener&gt;<br />
            7  &lt;listener-class&gt;org.activemq.web.SpringBrokerContextListener&lt;/listener-class&gt;<br />
            8  &lt;/listener&gt;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr></center>
<p>将这一段代码放到web.xml里。注意到activemq.xml文件，是jms服务器的具体配置：
</p>
<center><ccid_nobr>
<table bordercolordark="#ffffff" bordercolorlight="black" align="center" border="1" cellpadding="2" cellspacing="0" width="400">
    <tbody>
        <tr>
            <td style="font-size: 9pt;" bgcolor="#e6e6e6">
            <pre><ccid_code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
            &lt;!DOCTYPE beans PUBLIC <br />
            "-//ACTIVEMQ//DTD//EN" <br />
            "http://activemq.org/dtd/activemq.dtd"&gt;<br />
            &lt;beans&gt;<br />
            <br />
            &lt;!-- ===================== --&gt;<br />
            &lt;!-- ActiveMQ Broker Configuration --&gt;<br />
            &lt;!-- ===================== --&gt;<br />
            &lt;broker&gt;<br />
            &lt;connector&gt;<br />
            &lt;tcpServerTransport <br />
            uri="tcp://localhost:61616" <br />
            useAsyncSend="true"<br />
            maxOutstandingMessages="50"/&gt;<br />
            &lt;/connector&gt;<br />
            <br />
            &lt;!-- to enable Stomp support uncomment this<br />
            &lt;connector&gt;<br />
            &lt;serverTransport <br />
            uri="stomp://localhost:61626"/&gt;<br />
            &lt;/connector&gt;<br />
            --&gt;<br />
            <br />
            &lt;persistence&gt;<br />
            &lt;jdbcPersistence<br />
            dataSourceRef="oracle-ds"/&gt;<br />
            &lt;/persistence&gt;<br />
            &lt;/broker&gt;<br />
            <br />
            &lt;!-- ======================= --&gt;<br />
            &lt;!-- JDBC DataSource Configurations --&gt;<br />
            &lt;!-- ======================= --&gt;<br />
            <br />
            &lt;!-- The Derby Datasource <br />
            that will be used by the Broker --&gt;<br />
            &lt;bean id="derby-ds" class=<br />
            "org.apache.commons.dbcp.BasicDataSource"<br />
            destroy-method="close"&gt;<br />
            &lt;property name="driverClassName"&gt;<br />
            &lt;value&gt;<br />
            org.apache.derby.jdbc.EmbeddedDriver<br />
            &lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="url"&gt;<br />
            &lt;!-- Use a URL like <br />
            'jdbc:hsqldb:hsql://localhost:9001' <br />
            if you want to connect to a remote hsqldb --&gt;<br />
            &lt;value&gt;<br />
            jdbc:derby:derbydb;create=true<br />
            &lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="username"&gt;<br />
            &lt;value&gt;&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="password"&gt;<br />
            &lt;value&gt;&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="poolPreparedStatements"&gt;<br />
            &lt;value&gt;true&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;/bean&gt;<br />
            &lt;/beans&gt;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr></center>
<p>此时，在启动你的TOMCAT的时候会看到JMS服务器已经绑到了上面。</p>
</span></p>
<img src ="http://www.blogjava.net/libin2722/aggbug/249367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-12-31 18:07 <a href="http://www.blogjava.net/libin2722/articles/249367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)Apache+JK+Tomcat负载平衡配置</title><link>http://www.blogjava.net/libin2722/articles/225835.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 31 Aug 2008 01:37:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/225835.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/225835.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/225835.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/225835.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/225835.html</trackback:ping><description><![CDATA[<p>网上关于Apache + JK + Tomcat的集群配置例子很多，按着例子配置下来，基本都能运行，不过，在一些重要的地方却没有进一步的说明。这次公司一个产品就是采用Apache+JK+Tomcat集群，在整个配置、测试过程中，遇到了许多的问题，经过不断测试、摸索，最后总算是搞定了，性能也达到了预期的目标。针对网上的例子，感觉有必要再详细的介绍一下我的配置过程，对一些要特别注意的地方进行补充。<br />
<br />
集群有别于分布式的解决方案，它采用的是每台服务器运行相同应用的策略，由负责平衡的服务器进行分流，这对提高整个系统的并发量及吞吐量是更有效的办法。而集群对请求的处理又有两种不同的方式：负载平衡、状态复制(即集群)，状态复制需要在各服务器间复制应用状态，而负载平衡则不用，每台服务器都是独立的。实践证明，在各应用服务器之间不需要状态复制的情况下，负载平衡可以达到性能的线性增长及更高的并发需求。<br />
<br />
对于集群的其它基础知识，在此就不再做累赘。以下就这次Apache + JK + Tomcat的负载平衡配置进行总结，重点关注整个配置及注意事项。<br />
<br />
准备软件<br />
1、&nbsp;&nbsp;Tomcat或JBoss（本文档中采用的是JBoss4.0.2）；<br />
<br />
2、&nbsp;&nbsp;apache2.0.54是开源的Web服务器，下载地址为： <a href="http://www.apache.org/dist/httpd/binaries/" target="_blank"><font color="#000000">http://www.apache.org/dist/httpd/binaries/</font></a> ；<br />
<br />
3、&nbsp;&nbsp;mod_jk-1.2.14-apache-2.0.54.so模块,jk是mod_jserv的替代者，它是Tomcat-Apache插件，为Apache和Tomcat的连接器，处理Tomcat和Apache之间的通信，在集群配置中充当负载均衡器的作用，当前的最新版本为1.2.15，不过不同JK版本与不同的Apache版本之间的搭配有一些差异，有的甚至配不起来。JK2是符合apache2.x系列的新品，但由于其配置太过麻烦，使用的人很少，所以目前已停止开发，所以我们采用了jk连接器，下载地址：<a href="http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/" target="_blank"><font color="#000000">http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/</font></a>。<br />
<br />
集群与负载平衡<br />
使用mod_jk默认的以轮循方式进行平衡负载，假设有四个服务器节点，有10个请求，则四个节点分别接受请求编号如下：<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 节点1&nbsp;&nbsp;节点2&nbsp;&nbsp;节点3&nbsp;&nbsp;节点4<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 3&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;4<br />
&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;5&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;6&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 7&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;8<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;9&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;10<br />
<br />
而集群方式也是使用这种方法进行平衡。Tomcat中的集群原理是通过组播的方式进行节点的查找并使用TCP连接进行会话的复制。<br />
<br />
&nbsp; &nbsp; 集群不同于负载平衡的是，由于集群服务需要在处理请求之间不断地进行会话复制，复制后的会话将会慢慢变得庞大，因此它的资源占用率是非常高的，如果在并发量大的应用中，复制的会话大小会变得相当大，而使用的总内存更是会迅速升高。<br />
<br />
&nbsp; &nbsp; 但集群的会话复制，增加了系统的高可用性。由于在每台服务器都保存有用户的Session信息，如果服务器群中某台当机，应用可以自动切换到其它服务器上继续运行，而用户的信息不会丢失，这提高了应用的冗错性。<br />
<br />
具体采用负载平衡还是集群，这要看应用的需求了。<br />
<br />
安装配置Apache<br />
1、下载Apache的安装程序apache_2.0.54-win32-x86-no_ssl.exe后，安装很简单，一路回车，就此略过。<br />
<br />
2、安装完毕后，将下载的mod_jk-1.2.14-apache-2.0.54.so复制到Apache安装目录下的modules子目录中。<br />
<br />
3、然后进入Apache安装目录下的conf子目录中，打开httpd.conf配置文件，在最后插入以下一行：<br />
<br />
<font color="#0000ff">Include conf/mod_jk.conf</font><br />
<br />
4、&nbsp;&nbsp;在conf子目录下，建立一个新的配置文件：mod_jk.conf，此文件为Apache加载连接器的配置文件，文件名可修改，但要与httpd.conf中Include的文件名一致，内容如下：<br />
<br />
# Load mod_jk module. Specify the filename<br />
<br />
# of the mod_jk lib you&#8217;ve downloaded and<br />
<br />
# installed in the previous section<br />
<br />
#加载mod_jk模块<br />
<br />
LoadModule jk_module modules/mod_jk-1.2.14-apache-2.0.54.so<br />
<br />
# Where to find workers.properties<br />
<br />
JkWorkersFile conf/workers2.properties<br />
<br />
# Where to put jk logs<br />
<br />
JkLogFile logs/mod_jk.log<br />
<br />
# Set the jk log level [debug/error/info]<br />
<br />
JkLogLevel info<br />
<br />
# Select the log format<br />
<br />
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "<br />
<br />
# JkOptions indicate to send SSL KEY SIZE,<br />
<br />
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories<br />
<br />
# JkRequestLogFormat set the request format<br />
<br />
JkRequestLogFormat "%w %V %T"<br />
<br />
# 请求分发配置，可以配置多项<br />
<br />
<font color="#0000ff">JkMount /* loadbalancer</font><br />
<br />
<br />
#关掉主机Lookup，如果为on，很影响性能，可以有10多秒钟的延迟。<br />
HostnameLookups Off<br />
<br />
注：蓝色加粗的两行是重点，第一句是Apache加载JK模块用的；第二句为配置哪些URL请求将由负载平衡器来处理。<br />
<br />
5、&nbsp;&nbsp;在conf子目录下，建立一个新的配置文件：workers2.properties，此文件为负载平衡的配置文件，文件名不能修改，这是JK默认的名字，内容如下：<br />
<br />
worker.list=loadbalancer<br />
<br />
# Define the first node...<br />
<br />
worker.server99.port=8009<br />
<br />
worker.server99.host=192.168.11.99<br />
<br />
worker.server99.type=ajp13<br />
<br />
worker.server99.lbfactor=1 <br />
<br />
worker.server99.local_worker=1<br />
<br />
worker.server99.cachesize=1000<br />
<br />
worker.server99.cache_timeout=600<br />
<br />
worker.server99.socket_keepalive=1<br />
<br />
worker.server99.socket_timeout=0<br />
<br />
worker.server99.reclycle_timeout=300<br />
<br />
worker.server99.retries=3<br />
<br />
# Define the second node...<br />
<br />
worker.server202.port=8009<br />
<br />
worker.server202.host=192.168.11.202<br />
<br />
worker.server202.type=ajp13<br />
<br />
worker.server202.lbfactor=1<br />
<br />
worker.server202.local_worker=1<br />
<br />
worker.server202.cachesize=1000<br />
<br />
worker.server202.cache_timeout=600<br />
<br />
worker.server202.socket_keepalive=1<br />
<br />
worker.server202.socket_timeout=0<br />
<br />
worker.server202.reclycle_timeout=300<br />
<br />
worker.server202.retries=3<br />
<br />
# Now we define the load-balancing behaviour<br />
<br />
worker.loadbalancer.type=lb<br />
<br />
worker.retries=3<br />
<br />
<font color="#0000ff">worker.loadbalancer.balance_workers=server99 ,server202<br />
<br />
worker.loadbalancer.sticky_session=true<br />
<br />
worker.loadbalancer.sticky_session_force=true</font><br />
<br />
注：以上定义了两个worker，一个为server99，另一个为server202，定义了一个负载平衡服务器loadbalancer，其中标蓝色的为重点配置项，相关的详细说明可以看官方的网站文档：<a href="http://tomcat.apache.org/connectors-doc/" target="_blank"><font color="#000000">http://tomcat.apache.org/connectors-doc/</font></a>，其它节点的定义可以直接Copy，修改一下节点名及IP就好了。<br />
A、worker.list=loadbalancer<br />
<br />
设定工作的负载平衡器，各Tomcat节点不能加入此列表。<br />
<br />
B、worker.server99.lbfactor<br />
<br />
负载平衡的权重比，如果此权重比越大，则分配到此节点的请求越多，如以上两个节点的权重比为1:1，则为平均分配。<br />
<br />
C、worker.loadbalancer.balance_workers=server99,server202<br />
<br />
&nbsp; &nbsp;指定此负载平衡器负责的Tomcat应用节点。<br />
<br />
D、worker.loadbalancer.sticky_session=true<br />
<br />
&nbsp; &nbsp;此处指定集群是否需要会话复制，如果设为true，则表明为会话粘性，不进行会话复制，当某用户的请求第一次分发到哪台Tomcat后，后继的请求会一直分发到此Tomcat服务器上处理；如果设为false，则表明需求会话复制。<br />
<br />
E、worker.loadbalancer.sticky_session_force=true<br />
<br />
&nbsp; &nbsp;如果上面的sticky_session设为true时，建议此处也设为true，此参数表明如果集群中某台Tomcat服务器在多次请求没有响应后，是否将当前的请求，转发到其它Tomcat服务器上处理；此参数在sticky_session=true时，影响比较大，会导致转发到其它Tomcat服务器上的请求，找不到原来的session，所以如果此时请求中有读取session中某些信息的话，就会导致应用的null异常。<br />
<br />
6、Apache服务器的配置文件httpd.conf中，默认有三个参数对性能的影响比较大，但根据不同的性能要求，参数的表现又不一样，太小并发提不上去，太大性能反而不好，建议根据项目的需要，实际做个测试，如并发要求800的话，可以设定为：<br />
<br />
#一个连接的最大请求数量<br />
<br />
MaxKeepAliveRequests　1000（值为0，则不限制数量）<br />
<br />
#每个进程的线程数，最大1920。NT只启动父子两个进程，不能设置启动多个进程<br />
<br />
ThreadsPerChild　　　　1000（最大为1920）<br />
<br />
#每个子进程能够处理的最大请求数<br />
<br />
MaxRequestsPerChild&nbsp; &nbsp;1000（值为0，则不限制数量）<br />
<br />
这三个参数要根据不同的需求，不同的服务器进行调整。<br />
<br />
安装配置Tomcat或JBoss<br />
1、对于Tomcat或JBoss的安装，这里不做说明，目前我们是采用Apache+JBoss，不过，JBoss也是用的Tomcat，所以这里的配置也是适合Tomcat的；<br />
<br />
2、对于JBoss的配置，很简单，只需要改两个地方就可以了：<br />
<br />
第一个地方：进入jboss-4.0.2\server\default\deploy\jbossweb-tomcat55.sar，打开server.xml，大约在第32行左右，有，在其中加入一个参数，变为：<br />
<br />
Engine name="jboss.web" defaultHost="localhost"&gt;<br />
<br />
给它增加一个jvmRoute属性：<br />
<br />
<font color="#0000ff">&lt;Engine jvmRoute="server1" name="jboss.web" defaultHost="localhost"&gt;</font><br />
请注意，jvmRoute的值必须和mod_jk中的节点名字正确对应，否则无法正确路由。Cluster中的所有节点都应该做相应的配置。<br />
<br />
Jboss的配置完成了，下面需要在你的web应用中修改配置文件，让它支持集群。<br />
<br />
在WEB-INF\web.xml中加入属性：&nbsp; &nbsp; &lt;distributable/&gt;<br />
<br />
Ok，基于用户的cluster完成了，每个用户会绑定都某个节点上进行交互。这种绑定是如何完成的呢？原来apache把客户分发到节点后，该节点会在用户的session id后面加上此节点的路由名称，变成这个样子：<br />
<br />
Efdfxxd98daja87daj76da2dka**,server1<br />
<br />
&nbsp; &nbsp; 有了这个标志，就能分辨该session属于哪个节点。<br />
<br />
第二个地方：进入jboss-4.0.2\server\default\deploy\jbossweb-tomcat55.sar\META-INF目录，打开jboss-service.xml，大约在110行，有false，将其改为：true<br />
<br />
这里有一个需要特别注意的地方，JBoss的Tomcat中，关于AJP连接协议的默认配置，对于大并发量是不够用的，要做一些修改，进入jboss-4.0.2\server\default\deploy\jbossweb-tomcat55.sar，打开server.xml，找到的地方，这里是定义AJP连接器的地方，它的配置中没有maxThreads项，默认为200，我们可以做修改：<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;emptySessionPath="true" enableLookups="false" redirectPort="8443" <br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;protocol="AJP/1.3" maxThreads="3000"/&gt;<br />
<br />
maxThreads的值要看你的并发量多大，设置太大也不好。<br />
<br />
运行至此，整个配置全部完成，注意一点是，在各JBoss节点，重启或新增加一个JBoss节点时，需要重新启动Apache，而对于服务器群中某个JBoss节点shutdown，Apache会自动侦测，不用重新启动。<br />
<br />
如果在运行过程中，群中的某个JBoss节点shutdown，则已登录到此服务器上的用户的请求将出错，此服务器负责的session将丢失，但Apache会自动侦测到此服务器已shutdown，后继的新请求将不会再引导到此节点。<br />
<br />
对于负责请求分发的Apache服务器，需要消耗大量的CPU资源，因此如果在测试过程中出现一些Service Temporarily Unavailable或Server&nbsp;&nbsp;has shut down the connection prematurely这样的错误，这一般都是服务器配置不够好引起的，或者是Apache、Tomcat、及应用中的某些配置不够使用，这时候就要考虑换更好的机器或优化应用中的配置。<br />
<br />
<br />
常见问题<br />
<br />
一、cannot connect to server：无法连接到服务器。这种情况是服务器的配置有问题，服务器无法承受过多的并发连接了，需要优化服务器的配置：<br />
<br />
如操作系统采用更高版本，如windows 2003 server，<br />
<br />
优化tomcat配置：maxThreads="500" minSpareThreads="400" maxSpareThreads="450"<br />
<br />
但是tomcat 最多支持500个并发访问<br />
<br />
优化apache配置：<br />
<br />
ThreadsPerChild 1900 <br />
<br />
MaxRequestsPerChild&nbsp;&nbsp;10000<br />
<br />
二、 Action.c(10): Error -27791: Server&nbsp;&nbsp;has shut down the connection prematurely<br />
<br />
HTTP Status-Code=503 (Service Temporarily Unavailable)<br />
一般都是由于服务器配置不够好引起的，需要优化硬件和调整程序了。<br />
<br />
三、无法处理请求：<br />
<br />
当我们输入 ***.do 命令后，apache却返回错误信息，而连接tomcat却没有问题。原因是没有把.do命令转发给tomcat处理。解决方法如下：<br />
<br />
在apache配置文件中配置如下内容：<br />
<br />
<font color="#000080">JkMount /*.jsp loadbalancer<br />
<br />
JkMount /*.do loadbalancer</font></p>
<p><font color="#000080"></font></p>
<p>估计最高在线人数是3万，并发人数最多100人。开发的网站是否能否承受这个压力，如何确保网站的负荷没有问题，经过研究决定如下：<br />
（1） 采用负载平衡和集群技术，初步机构采用Apache+Tomcat的机群技术。<br />
（2） 采用压力测试工具，测试压力。工具是Loadrunner。<br />
硬件环境搭建：<br />
为了能够进行压力测试，需要搭建一个环境。刚开始时，测试在公司局域网内进行，但很快发现了一个问题，即一个脚本的压力测试结果每次都不一样，并且差别很大。原来是受公司网络的影响，于是决定搭建一个完全隔离的局域网测试。搭建后的局域网配置如下：<br />
（1） 网络速度：100M<br />
（2） 三台服务器：<br />
负载服务器 ：操作系统windows2003，<br />
Tomcat服务器：操作系统windows2000 Professional<br />
数据库服务器：操作系统windows2000 Professional<br />
三台机器的cpu 2.4 G, 内存 1G。<br />
软件环境搭建：<br />
软件的版本如下：<br />
Apache 版本：2.054，<br />
Tomcat5.0.30,<br />
mysql ：4.1.14.<br />
JDK1.5<br />
压力测试工具：Loadrunner7.8。 <br />
<br />
负载平衡方案如下：<br />
一台机器（操作系统2003）安装apache，作为负载服务器，并安装tomcat作为一个worker；一个单独安装tomcat，作为第二个worker；剩下的一台单独作为数据库服务器。<br />
Apache和tomcat的负载平衡采用JK1.2.14（没有采用2.0，主要是2.0不再维护了）。<br />
集群方案：<br />
采用Tomcat本身的集群方案。在server.xml配置。<br />
压力测试问题：<br />
压力测试后，发现了一些问题，现一一列出来：<br />
（1） 采用Tocmat集群后，速度变得很慢。因为集群后，要进行session复制，导致速度较慢。Tomcatd的复制，目前不支持application复制。复制的作用，主要用来容错的，即一台机器有故障后，apache可以把请求自动转发到另外一个机器。在容错和速度的考虑上，我们最终选择速度，去掉了Tomcat集群。<br />
（2） 操作系统最大并发用户的限制：<br />
为了采用网站的压力，我们开始的时候，仅测试Tomcat的最大负载数。Tomcat服务器安装的操作系统是windows2000 Professional。当我们用压力测试工具，并发测试时，发现只要超过15个并发用户，会经常出现无法连接服务器的情况。经过研究，发现是操作系统的问题：windows2000 Professional 支持的并发访问用户有限，默认的好像是15个。于是我们把操作系统全部采用windows2003 server版本。<br />
（3） 数据库连接池的问题：<br />
测试数据库连接性能时，发现数据库连接速度很慢。每增加一些用户，连接性能就差了很多。我们采用的数据库连接池是DBCP，默认的初始化为50个，应该不会很慢吧。查询数据库的连接数，发现初始化，只初始化一个连接。并发增加一个用户时，程序就会重新创建一个连接，导致连接很慢。原因就在这里了。如何解决呢？偶尔在JDK1.4下的Tomcat5.0.30下执行数据库连接压力测试，发现速度很快，程序创建数据库连接的速度也是很快的。看来JDK1.5的JDBC驱动程序有问题。于是我们修改 JDK的版本为1.4.<br />
<br />
（4） C3P0和DBCP<br />
C3P0是Hibernate3.0默认的自带数据库连接池，DBCP是Apache开发的数据库连接池。我们对这两种连接池进行压力测试对比，发现在并发300个用户以下时，DBCP比C3P0平均时间快1秒左右。但在并发400个用户时，两者差不多。<br />
<br />
速度上虽然DBCP比C3P0快些，但是有BUG：当DBCP建立的数据库连接，因为某种原因断掉后，DBCP将不会再重新创建新的连接，导致必须重新启动Tomcat才能解决问题。DBCP的BUG使我们决定采用C3P0作为数据库连接池。<br />
调整后的方案：<br />
操作系统Windows2003 server版本<br />
JDK1.4<br />
Tomcat 5.0.30<br />
数据库连接池C3P0<br />
仅采用负载平衡，不采用集群。<br />
软件的配置：<br />
Apache配置：主要配置httpd.conf和新增加的文件workers.properties<br />
Httpd.conf：<br />
#一个连接的最大请求数量<br />
MaxKeepAliveRequests 10000 <br />
#NT环境，只能配置这个参数来提供性能<br />
<ifmodule c=""  mpm_winnt.></ifmodule><br />
#每个进程的线程数，最大1920。NT只启动父子两个进程，不能设置启动多个进程<br />
ThreadsPerChild 1900 <br />
每个子进程能够处理的最大请求数<br />
MaxRequestsPerChild 10000<br />
<br />
<br />
# 加载mod_jk<br />
#<br />
LoadModule jk_module modules/mod_jk.so<br />
#<br />
# 配置mod_jk<br />
#<br />
JkWorkersFile conf/workers.properties<br />
JkLogFile logs/mod_jk.log<br />
JkLogLevel info<br />
#请求分发，对jsp文件，.do等动态请求交由tomcat处理<br />
DocumentRoot \"C:/Apache/htdocs\"<br />
JkMount /*.jsp loadbalancer<br />
JkMount /*.do loadbalancer<br />
JkMount /servlet/* loadbalancer<br />
#关掉主机Lookup，如果为on，很影响性能，可以有10多秒钟的延迟。<br />
HostnameLookups Off<br />
#缓存配置<br />
LoadModule cache_module modules/mod_cache.so<br />
LoadModule disk_cache_module modules/mod_disk_cache.so<br />
LoadModule mem_cache_module modules/mod_mem_cache.so<br />
<br />
<ifmodule c=""  mod_cache.></ifmodule><br />
CacheForceCompletion 100<br />
CacheDefaultExpire 3600<br />
CacheMaxExpire 86400<br />
CacheLastModifiedFactor 0.1<br />
<br />
<ifmodule c=""  mod_disk_cache.></ifmodule><br />
CacheEnable disk /<br />
CacheRoot c:/cacheroot<br />
CacheSize 327680<br />
CacheDirLength 4<br />
CacheDirLevels 5<br />
CacheGcInterval 4<br />
<br />
<ifmodule c=""  mod_mem_cache.></ifmodule><br />
CacheEnable mem /<br />
MCacheSize 8192<br />
MCacheMaxObjectCount 10000<br />
MCacheMinObjectSize 1<br />
MCacheMaxObjectSize 51200<br />
<br />
<br />
worker. Properties文件<br />
#<br />
# workers.properties ，可以参考<br />
http://jakarta.apache.org/tomcat/connectors-doc/config/workers.html <br />
# In Unix, we use forward slashes:<br />
ps=<br />
<br />
# list the workers by name<br />
<br />
worker.list=tomcat1, tomcat2, loadbalancer<br />
<br />
# ------------------------<br />
# First tomcat server<br />
# ------------------------<br />
worker.tomcat1.port=8009<br />
worker.tomcat1.host=localhost<br />
worker.tomcat1.type=ajp13<br />
<br />
# Specify the size of the open connection cache.<br />
#worker.tomcat1.cachesize<br />
<br />
#<br />
# Specifies the load balance factor when used with<br />
# a load balancing worker.<br />
# Note:<br />
# ----&gt; lbfactor must be &gt; 0<br />
# ----&gt; Low lbfactor means less work done by the worker.<br />
worker.tomcat1.lbfactor=900<br />
<br />
# ------------------------<br />
# Second tomcat server<br />
# ------------------------<br />
worker.tomcat1.port=8009<br />
worker.tomcat1.host=202.88.8.101<br />
worker.tomcat1.type=ajp13<br />
<br />
# Specify the size of the open connection cache.<br />
#worker.tomcat1.cachesize<br />
<br />
#<br />
# Specifies the load balance factor when used with<br />
# a load balancing worker.<br />
# Note:<br />
# ----&gt; lbfactor must be &gt; 0<br />
# ----&gt; Low lbfactor means less work done by the worker.<br />
worker.tomcat1.lbfactor=2000<br />
<br />
# ------------------------<br />
# Load Balancer worker<br />
# ------------------------<br />
<br />
#<br />
# The loadbalancer (type lb) worker performs weighted round-robin<br />
# load balancing with sticky sessions.<br />
# Note:<br />
# ----&gt; If a worker dies, the load balancer will check its state<br />
# once in a while. Until then all work is redirected to peer<br />
# worker.<br />
worker.loadbalancer.type=lb<br />
worker.loadbalancer.balanced_workers=tomcat1,tomcat2<br />
<br />
#<br />
# END workers.properties<br />
#<br />
<br />
Tomcat1配置:<br />
<!--配置server.xml<br />
去掉8080端口，即注释掉如下代码：--><br />
<connector></connector>port=\"8080\" maxThreads=\"150\" minSpareThreads=\"25\" maxSpareThreads=\"75\"<br />
enableLookups=\"false\" redirectPort=\"8443\" acceptCount=\"100\"<br />
debug=\"0\" connectionTimeout=\"20000\" <br />
disableUploadTimeout=\"true\" /&gt;<br />
<br />
<!--配置8009端口如下：--><br />
<connector port='\"8009\"'></connector>maxThreads=\"500\" minSpareThreads=\"400\" maxSpareThreads=\"450\"<br />
enableLookups=\"false\" redirectPort=\"8443\" debug=\"0\"<br />
protocol=\"AJP/1.3\" /&gt;<br />
<!--配置引擎--><br />
<engine name='\"Catalina\"' defaulthost='\"localhost\"' debug='\"0\"' jvmroute='\"tomcat1\"'></engine><br />
<br />
启动内存配置,开发configure tomcat程序即可配置：<br />
Initial memory pool: 200 M<br />
Maxinum memory pool:300M<br />
Tomcat2配置：<br />
配置和tomcat1差不多，需要改动的地方如下：<br />
<!--配置引擎--><br />
<engine name='\"Catalina\"' defaulthost='\"localhost\"' debug='\"0\"' jvmroute='\"tomcat2\"'></engine><br />
<br />
启动内存配置,开发configure tomcat程序即可配置：<br />
Initial memory pool: 512 M<br />
Maxinum memory pool:768M<br />
Mysql配置：<br />
Server类型：Dedicated MySQL Server Machine <br />
Database usage:Transational Database Only<br />
并发连接数量：Online Transaction Processing(OLTP)<br />
字符集：UTF8<br />
数据库连接池的配置：<br />
我们采用的是spring 框架，配置如下：<br />
<property name='\"hibernateProperties\"'><br />
<props></props>
<br />
<prop key='\"hibernate.dialect\"'></prop>
org.hibernate.dialect.MySQLDialect<br />
<prop key='\"hibernate.connection.driver_class\"'></prop>
com.mysql.jdbc.Driver<br />
<prop key='\"hibernate.connection.url\"'></prop>
jdbc:mysql://202.88.1.103/db <br />
<prop key='\"hibernate.connection.username\"'></prop>
sa<br />
<prop key='\"hibernate.connection.password\"'></prop>
<br />
<br />
<prop key='\"hibernate.show_sql\"'></prop>
false<br />
<prop key='\"hibernate.use_sql_comments\"'></prop>
false<br />
<br />
<prop key='\"hibernate.cglib.use_reflection_optimizer\"'></prop>
true<br />
<prop key='\"hibernate.max_fetch_depth\"'></prop>
2<br />
<br />
<prop key='\"hibernate.c3p0.max_size\"'></prop>
200<br />
<prop key='\"hibernate.c3p0.min_size\"'></prop>
5<br />
<prop key='\"hibernate.c3p0.timeout\"'></prop>
12000<br />
<prop key='\"hibernate.c3p0.max_statements\"'></prop>
50<br />
<prop key='\"hibernate.c3p0.acquire_increment\"'></prop>
1 <br />
<br />
</property>
<br />
其他的没有额外配置。<br />
LoadRunner 常见问题：<br />
（1）sofeware caused connction：这种情况，一般是脚本有问题，或者loadrunner有问题。解决方法：重新启动机器，或者重新录制脚本，估计是loadrunner的bug。<br />
（2）cannot connect to server:无法连接到服务器。这种情况是服务器的配置有问题，服务器无法承受过多的并发连接了。需要优化服务器的配置，<br />
如操作系统采用windows 2003 server，<br />
优化tomcat配置：maxThreads=\"500\" minSpareThreads=\"400\" maxSpareThreads=\"450\"。但是tomcat 最多支持500个并发访问<br />
优化apache配置：<br />
ThreadsPerChild 1900 <br />
MaxRequestsPerChild 10000<br />
其他的错误如：<br />
Action.c(10): Error -27791: Server has shut down the connection prematurely<br />
HTTP Status-Code=503 (Service Temporarily Unavailable)<br />
一般都是由于服务器配置不够好引起的，按照问题（2）处理，如果仍旧不行，需要优化硬件和调整程序了。<br />
Apache问题：<br />
（1） File does not exist: C:/Apache/htdocs/favicon.ico：<br />
这个问题是apache，htdocs目录没有favicon.ico文件引起的，该文件是网站的图标，仅在firefox,myIE等浏览器出现。<br />
（2） 图片无法显示：<br />
配置apache后，却无法显示图片。<br />
解决方法：把程序的图片，按照程序结构copy到apache的htdocs目录下。<br />
（3） 无法处理请求：<br />
<br />
没有问题。原因是没有把.do命令转发给tomcat处理。解决方法如下：<br />
在apache配置文件中配置如下内容：<br />
DocumentRoot \"C:/Apache/htdocs\"<br />
JkMount /*.jsp loadbalancer<br />
JkMount /*.do loadbalancer<br />
<br />
<br />
总结：<br />
网站的压力测试，涉及的知识面挺广的，不仅要熟悉压力测试,还要善于发现问题，要知道如何解决。最重要的一点，要有良好的测试方法。刚开始测试时，可以从最简单的测试脚本入手，不需要太复杂的脚本，这样便于发现问题。如我们刚开始时，就从一个简单的下载登陆界面的脚本入手，测试一个tomcat的压力负载。一个简单的获取登陆的脚本，帮助我们优化了tomcat的配置；后来再测试数据库连接，也是一个简单的数据库连接脚本，帮助我们优化了数据库连接池；然后利用这些简单的脚本，测试apache的负载平衡，优化了apache配置。最后运行复杂的脚本，模拟多种角色的用户在不同时间下的处理，以测试网站压力负载。</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/225835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-08-31 09:37 <a href="http://www.blogjava.net/libin2722/articles/225835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转载）牛人写的Jboss集群</title><link>http://www.blogjava.net/libin2722/articles/222953.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Tue, 19 Aug 2008 03:18:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/222953.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/222953.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/222953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/222953.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/222953.html</trackback:ping><description><![CDATA[<div>
<div>
<div>
<div>
<div>
<h2 style="clear: both;"><font color="#0000ff">1&nbsp;概述</font></h2>
</div>
</div>
</div>
<p>集群允许一个应用同时运行在多个并发的服务器。负载分布在不同的服务器，即使有个别服务器崩溃，应用程序还可以通过别的服务器节点访问。集群是企业级应用的关键技术，可以通过简单地增加节点来提升性能。</p>
<p>JBoss支持集群，启动一个JBoss集群的最简单的方式是,使用run -c all命令在局域网内启动多个JBoss实例。这些服务器实例，都使用all配置集，自动地构建一个集群。</p>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.1&nbsp;定义</font></h3>
</div>
</div>
</div>
<p>一个集群是由一系列节点组成。在一个JBoss集群中，一个节点是一个JBoss服务器实例，要构建一个集群，必须将几个JBoss服务器实例组合在一起。在一个局域网可能有多个集群，为了区分他们，每个集群必须有唯一的名称。</p>
<p>下图构建一个网络，包含三个集群。节点可以在任何时候添加到集群或者从集群中</p>
<div align="center"><img src="http://docs.jboss.com/jbossas/guides/clusteringguide/r2/en/html_single/images/clustering-Partition.png" alt="Clusters and server nodes" align="center" /></div>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>注意:</h3>
<p>一个JBoss服务器实例可以同时在多个集群，但是不推荐这样做，因为会增加管理复杂性。</p>
</div>
<p>JBoss服务器实例通过<tt>deploy/cluster-service.xml</tt> 文件中的ClusterPartition MBean指定属于哪一个集群。所有有同样的ClusterPartition MBean配置的节点属性同一个集群。因此，如果想在同一个局域网构建两个集群，只需要创建两个不同的ClusterPartition配置即可。如果某一个节点启动时，集群还不存在，会创建这个集群，同时当属于一个集群的所有节点移除时，集群也会被移除。</p>
<p>下面的示例是JBoss发布包的缺省定义，通过使用此缺省集群设置启动服务器，将可以构建一个缺省集群名称为<tt>DefaultPartition的集群。</tt></p>
<div>
<ol>
    <li>&lt;mbean&nbsp;code="org.jboss.ha.framework.server.ClusterPartition"&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;name="jboss:service=DefaultPartition"&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="PartitionName"&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${jboss.partition.name:DefaultPartition} &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;attribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="NodeAddress"&gt;${jboss.bind.address}attribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="DeadlockDetection"&gt;Falseattribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Increase&nbsp;for&nbsp;large&nbsp;states&nbsp;--&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="StateTransferTimeout"&gt;30000attribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="PartitionConfig"&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;... &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;attribute&gt;&nbsp;&nbsp; </li>
    <li>mbean&gt;&nbsp;&nbsp; </li>
</ol>
</div>
<div>xml 代码</div>
<p>这里省略了详细的JGroups协议配置，JGoups处理底层的节点之间的点对点通信，稍后将讨论其具体配置。<tt>ClusterPartition</tt> MBean可配置的属性包括：</p>
<div>
<ul type="disc">
    <li>
    <p><strong>PartitionName</strong> 缺省值是<tt>DefaultPartition，可选属性，用来指定集群的名称。</tt></p>
    </li>
    <li>
    <p><strong>NodeAddress</strong> 设置节点的IP地址。</p>
    </li>
    <li>
    <p><strong>DeadlockDetection</strong> 缺省值为false，设置JGroups是否基于每个请求都运行消息死锁检测算法。</p>
    </li>
    <li>
    <p><strong>StateTransferTimeout</strong> 缺省值是30000，设置集群之间的状态复制的超时值。</p>
    </li>
    <li>
    <p><strong>PartitionConfig</strong> 指定JGourp配置选项。</p>
    </li>
</ul>
</div>
<p>一个集群包含的所有节点，必须有同样的 <tt>PartitionName</tt> 和 <tt>ParitionConfig</tt> 元素。改变某些节点的这两个元素将导致集群分离，通过改变<tt>ParitionConfig</tt> 是更容易一些。</p>
<p>可以通过集群中的任何一个节点的JMX控制台查看当前集群信息（比如：<a href="http://hostname:8080/jmx-console">http://hostname:8080/jmx-console</a>），然后点击 <tt>jboss:service=DefaultPartition</tt> MBean，将可以看到当前集群的所有节点的IP地址列表。</p>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>注意</h3>
<p>A cluster (partition) contains a set of nodes that work toward a
same goal. Some clustering features require to sub-partition the
cluster to achieve a better scalability. For example, let's imagine
that we have a 10-node cluster and we want to replicate in memory the
state of stateful session beans on all 10 different nodes to provide
for fault-tolerant behaviour. It would mean that each node has to store
a backup of the 9 other nodes. This would not scale at all (each node
would need to carry the whole state cluster load). It is probably much
better to have some kind of sub-partitions inside a cluster and have
beans state exchanged only between nodes that are part of the same
sub-partition. The future JBoss
clustering implementation will support sub-partitions and it will allow
the cluster administrator to determine the optimal size of a
sub-partition. The sub-partition topology computation will be done
dynamically by the cluster.</p>
</div>
</div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.2 服务架构</font></h3>
</div>
</div>
</div>
<p>对于应用程序开发人员来讲，可能更关心集群的架构，JBoss支持两种类型的集群架构，一种是客户端的拦截器架构，比如代理和存根，还有一种是负载平衡器。</p>
<div>
<div>
<div>
<div>
<h4><font color="#0000ff">1.2.1 客户端拦截器架构</font></h4>
</div>
</div>
</div>
<p>JBoss应用服务器提供的大多数远程服务，包括JNDI,EJB,RMI等都要求客户端获取一个存根对象。存根对象由服务器生成，实现服务接口。客户端在本地调用存根对象，这些调用自动进行网络路由，激活服务器管理的服务对象。在一个集群环境中，服务器生成的存根对象也是一个拦截器实现，知道如何在集群包含的节点中路由请求。存根对象知道如何查找合适的服务器节点，编码调用参数，解码调用结果，并返回结果给客户端。</p>
<p>存根拦截器包含集群的相关信息，比如，所有可用的服务器节点的IP地址，负载平衡算法，以及当某个目标节点不可用时如何处理请求。每个请求中，服务器节点将用集群的最近的改变信息更新存根拦截器。比如，一个节点从集群中移除，当每个存根拦截器连接到任何一个激活的节点时，都将更新最新的配置信息。所有基于存根的操作对于客户来讲都是透明的，客户端拦截器集群架构如下图所示：</p>
<div>
<div align="center"><img src="http://docs.jboss.com/jbossas/guides/clusteringguide/r2/en/html_single/images/clustering-InterceptorArch.png" alt="The client-side interceptor (proxy) architecture for clustering" align="center" /></div>
</div>
</div>
<div>
<div>
<div>
<div>
<h4><font color="#0000ff">1.2.2 负载平衡器</font></h4>
</div>
</div>
</div>
<p>别的JBoss服务，特别是HTTP WEB服务，不要求客户端下载任何东西。客户直接通过某个通信协议发送请求并接受响应，比如HTTP协议。这种情况下，一个负载平衡器用来处理所有的请求并将这些请求派发给集群中的节点。负载平衡器通常是集群的一部分，它知道集群配置和恢复策略，客户端只需要知道负载平衡器。负载平衡器架构如下图所示：<img src="http://docs.jboss.com/jbossas/guides/clusteringguide/r2/en/html_single/images/clustering-BalancerArch.png" alt="The load balancer architecture for clustering" align="center" /></p>
<div>
</div>
<p>负载平衡器架构的一个潜在的问题是负载平衡器是所有请求的唯一入口，必须保证高的可用性。</p>
</div>
</div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.2.3 负载平衡策略</font></h3>
</div>
</div>
</div>
<p>客户拦截器架构和负载平衡器架构都使用负载平衡策略确定由哪一个服务器节点发送一个新的请求。下面描述JBoss AS的负载平衡策略。</p>
<div>
<div>
<div>
<div>
<h4><font color="#0000ff">1.2.3.1&nbsp;JBoss AS 3.0.x</font></h4>
</div>
</div>
</div>
<p>JBoss 3.0.x 中有如下两个负载平衡选项可用：</p>
<div>
<ul type="disc">
    <li>
    <p>Round-Robin (<tt>org.jboss.ha.framework.interfaces.RoundRobin</tt>)：每次调用被派发给一个新的节点，第一个节点是随机选择的。</p>
    </li>
    <li>
    <p>First Available (<tt>org.jboss.ha.framework.interfaces.FirstAvailable</tt>):：第一个可用的节点选为主节点，服务于随后每一个调用，主节点的选择是随机的。当集群中的节点发生变化时（因为节点启动或者停止），除非当前主节点依然可用，将重新选择一个可用的节点作为主节点。每个客户端拦截器或负载平衡器独立选择自己的主节点。</p>
    </li>
</ul>
</div>
</div>
<div>
<div>
<div>
<div>
<h4><font color="#0000ff">1.2.3.2 JBoss AS 3.2+</font></h4>
</div>
</div>
</div>
<p>JBoss 3.2+ 中增加了一个新的负载平衡选项 "First AvailableIdenticalAllProxies" (<tt>org.jboss.ha.framework.interfaces.FirstAvailableIdenticalAllProxies</tt>)，此选项和 "First Available" 策略有类似的策略，唯一的区别是选择的主节点被所有的客户端拦截器共享。</p>
<p>JBoss 3.2&nbsp;以后的版本中， 定义了"Proxy
Family"术语。is defined. A Proxy Family is a set of stub interceptors that
all make invocations against the same replicated target. For EJBs for
example, all stubs targeting the same EJB in a given cluster belong to
the same proxy family. All interceptors of a given family share the
same list of target nodes. Each interceptor also has the ability to
share arbitrary information with other interceptors of the same family.
A use case for the proxy family is give in <a href="http://docs.jboss.com/jbossas/guides/clusteringguide/r2/en/html_single/#clustering-session-slsb21" title="1.3.1.&nbsp;Stateless Session Bean in EJB 2.x">Section&nbsp;1.3.1, &#8220;Stateless Session Bean in EJB 2.x&#8221;</a>.</p>
</div>
</div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.2.4 布署</font></h3>
</div>
</div>
</div>
<p>在一个集群中布署应用程序最容易的方式是使用farming服务，就是将一个应用程序压缩文件（EAR,WAR或SAR)热布署到任一个节点的 <tt>all/farm/</tt> 目录，应用程序会自动地复制到集群中的其他节点。如果稍后有新的节点加入，新节点启动时也会自动从集群中复制应用程序并布署到本地。在集群运行的过程中，如果从任一节点的farm目录移除应用程序，这个应用程序将首先从本地卸载，然后再从集群的其他节点中卸载。应该手动从当前没有连接到集群的服务器节点中删除应用程序。</p>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>注意</h3>
<p>当前存在一个Bug，Farm布署服务只能在热布署压缩文件的方式中才能生效。如果你首先放一个应用程序在farm目录，然后启动服务器，这个应用程序将不会被检测并布署到集群中。</p>
</div>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>注意</h3>
<p>在farm目录中只能使用压缩文件，而不能使用展开的目录。</p>
</div>
<p>Farming 服务在JBoss AS发布版的all配置集中是缺省启用的，不需要手动设置。配置文件保存在deploy/deploy.last目录，如果需要在集群配置中启用farming服务，创建farm-service.xml文件如下，并拷贝到JBoss布署目录<tt>$JBOSS_HOME/server/your_own_config/deploy，确保在配置中已经启用集群服务。</tt>&nbsp;</p>
<div>
<div>xml 代码</div>
<div>
<ol>
    <li>xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"?&gt;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&lt;server&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;mbean&nbsp;code="org.jboss.ha.framework.server.FarmMemberService"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name="jboss:service=FarmMember,partition=DefaultPartition"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="PartitionName"&gt;DefaultPartitionattribute&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="ScanPeriod"&gt;5000attribute&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="URLs"&gt;farm/attribute&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;mbean&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>server&gt;&nbsp;&nbsp; </li>
</ol>
</div>
&nbsp;</div>
<p>&nbsp;&nbsp;F<tt>armMemberService</tt> MBean 可用的属性如下：</p>
<div>
<ul type="disc">
    <li>
    <p><strong>PartitionName</strong> 指定集群名字，缺省值为 <tt>DefaultPartition</tt>.</p>
    </li>
    <li>
    <p><strong>URLs</strong> 指定布署器监控布署文件的目录，如果不存在，MBean将创建。 "." 表示配置目录（比如 <tt>$JBOSS_HOME/server/all/）。</tt></p>
    </li>
    <li>
    <p><strong>ScanPeriod</strong> 指定文件夹的扫描周期，缺省值为5000。</p>
    </li>
</ul>
</div>
<p>Farming 服务是<tt>URLDeploymentScanner的扩展，用来扫描deploy目录，因此在<tt>FarmMemberService</tt> MBean中可以使用<tt>URLDeploymentScanner</tt> MBean 中定义的所有属性。</tt></p>
</div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.2.4 分布式状态复制服务</font></h3>
</div>
</div>
</div>
<p>集群环境中，分布式状态管理是集群必须提供的一个关键服务。比如一个有状态的会话Bean应用程序，会话状态必须在所有节点的Bean实例中保持同步，因此不管哪个节点服务请求，客户端应该得到同样的会话状态。实体Bean应用程序中，Bean实例必须在集群中进行缓存以减轻数据库负载。目前JBoss AS中的状态复制和分布式缓存由两种方式提供： <tt>HASessionState</tt> MBean 和 JBoss Cache 框架。</p>
<div>
<ul type="disc">
    <li>
    <p><tt>HASessionState</tt> MBean 基于EJB2.X有状态会话Bean和JBoss3.x和4.x的HTTP负载平衡器提供会话复制和分布式缓存服务。MBean相关定义在 <tt>all/deploy/cluster-service.xml</tt> 文件中。</p>
    </li>
    <li>
    <p>JBoss Cache 是一个分布式缓存框架，可以用在任何应用程序服务器环境，也可以独立使用，已经逐渐替换 <tt>HASessionState</tt> 服务。JBoss AS 整合JBoss Cache 为HTTP会话， EJB 3.0 会话和实体Bean,Hibernate持久对象提供缓存服务。这些缓存服务都在独立的MBean中定义。</p>
    </li>
</ul>
</div>
<div>
<div>
<div>
<div>
<h2 style="clear: both;"><font color="#0000ff">1.5&nbsp;HTTP服务</font></h2>
</div>
</div>
</div>
<p>HTTP会话复制用来在你的WEB客户端和集群的节点之间复制状态，那么当某一个节点崩溃时，集群中的其他节点可以恢复。要实现这个目的，必须执行两个步骤：</p>
<div>
<ul type="disc">
    <li>
    <p>会话状态复制</p>
    </li>
    <li>
    <p>请求负载平衡</p>
    </li>
</ul>
</div>
<p>如果使用all配置集启动JBoss，缺省会启用会话状态复制功能，只需要布署你的应用程序，会话状态就已经可以在集群中进行复制。</p>
<p>但是负载平衡需要额外的软件支持，作为一个常用的场景，我们将描述如何设置Apache和mod_jk。这个功能也可以通过专门的硬件或者其他软件来实现。</p>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>注意</h3>
<p>一个负载平衡器跟踪HTTP请求，根据和请求关联的会话，决定派发请求到合适的节点。这被称作使用sticky-sessions的负载平衡器：一
旦在某个节点创建了会话，随后的请求将由同一个节点进行处理。使用一个支持sticky-sessions的负载平衡器可以不用复制会话，没有会话状态复
制的花销，每个请求将是被同一个节点处理。但是一旦这个节点崩溃，保存在这个节点的所有客户会话都将丢失，客户必须登录进另一个节点，重新启动一个新的会
话。在某些情况，不复制HTTP会话是可以接受的，因为比较关键的状态都保存在数据库中，但是也有些情况下，丢失会话状态是无法接受的，这种情况下，会话
状态复制的花销是必须承受的。</p>
</div>
<p>Apache
是一个可以通过插入模块扩展功能的WEB服务器，mod_jk（最新的mod_jk2）模块的主要功能就是允许从Apache分发请求到一个
Servlet容器，还可以支持在多个Servlet容器中负载平衡HTTP调用（遵循sticky-sessions）。</p>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.5.1.&nbsp;下载软件</font></h3>
</div>
</div>
</div>
<p>从<tt><a href="http://httpd.apache.org/%C2%A0">http://httpd.apache.org/</a> 下载Apache,安装是非常直白的，不需要特别的配置，推荐使用2.0.x版本，这里假定Apache安装目录为APACHE_HOME。</tt>&nbsp;</p>
<p>然后从<a href="http://www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/">www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/</a>. 下载mod_jk模块，建议使用mod_jk 1.2.x版本。重命名下载的文件为mod_jk.so，拷贝到APACHE_HOME/modules/目录下。</p>
</div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.5.2.&nbsp;配置Apache使用mod_jk</font></h3>
</div>
</div>
</div>
<p>更改APACHE_HOME/conf/httpd.conf 文件，在文件尾部添加一行：</p>
<div>java 代码</div>
<div>
<ol>
    <li>#&nbsp;Include&nbsp;mod_jk's&nbsp;specific&nbsp;configuration&nbsp;file&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>Include&nbsp;conf/mod-jk.conf&nbsp;&nbsp;&nbsp;&nbsp; </li>
</ol>
</div>
<p>创建文件<tt>APACHE_HOME/conf/mod-jk.conf</tt>:</p>
<pre>
<div>java 代码</div>
<div>
<ol>
    <li>#&nbsp;Load&nbsp;mod_jk&nbsp;module &nbsp;&nbsp;</li>
    <li>#&nbsp;Specify&nbsp;the&nbsp;filename&nbsp;of&nbsp;the&nbsp;mod_jk&nbsp;lib &nbsp;&nbsp;</li>
    <li>LoadModule&nbsp;jk_module&nbsp;modules/mod_jk.so &nbsp;&nbsp;</li>
    <li>&nbsp; &nbsp;&nbsp;</li>
    <li>#&nbsp;Where&nbsp;to&nbsp;find&nbsp;workers.properties &nbsp;&nbsp;</li>
    <li>JkWorkersFile&nbsp;conf/workers.properties &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>#&nbsp;Where&nbsp;to&nbsp;put&nbsp;jk&nbsp;logs &nbsp;&nbsp;</li>
    <li>JkLogFile&nbsp;logs/mod_jk.log &nbsp;&nbsp;</li>
    <li>&nbsp; &nbsp;&nbsp;</li>
    <li>#&nbsp;Set&nbsp;the&nbsp;jk&nbsp;log&nbsp;level&nbsp;[debug/error/info] &nbsp;&nbsp;</li>
    <li>JkLogLevel&nbsp;info&nbsp; &nbsp;&nbsp;</li>
    <li>&nbsp; &nbsp;&nbsp;</li>
    <li>#&nbsp;Select&nbsp;the&nbsp;log&nbsp;format &nbsp;&nbsp;</li>
    <li>JkLogStampFormat&nbsp;&nbsp;"[%a&nbsp;%b&nbsp;%d&nbsp;%H:%M:%S&nbsp;%Y]"&nbsp;&nbsp;</li>
    <li>&nbsp; &nbsp;&nbsp;</li>
    <li>#&nbsp;JkOptions&nbsp;indicates&nbsp;to&nbsp;send&nbsp;SSK&nbsp;KEY&nbsp;SIZE &nbsp;&nbsp;</li>
    <li>JkOptions&nbsp;+ForwardKeySize&nbsp;+ForwardURICompat&nbsp;-ForwardDirectories &nbsp;&nbsp;</li>
    <li>&nbsp; &nbsp;&nbsp;</li>
    <li>#&nbsp;JkRequestLogFormat &nbsp;&nbsp;</li>
    <li>JkRequestLogFormat&nbsp;"%w&nbsp;%V&nbsp;%T"&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</li>
    <li>#&nbsp;Mount&nbsp;your&nbsp;applications &nbsp;&nbsp;</li>
    <li>JkMount&nbsp;/application/*&nbsp;loadbalancer &nbsp;&nbsp;</li>
    <li>&nbsp; &nbsp;&nbsp;</li>
    <li>#&nbsp;You&nbsp;can&nbsp;use&nbsp;external&nbsp;file&nbsp;for&nbsp;mount&nbsp;points. &nbsp;&nbsp;</li>
    <li>#&nbsp;It&nbsp;will&nbsp;be&nbsp;checked&nbsp;for&nbsp;updates&nbsp;each&nbsp;60&nbsp;seconds. &nbsp;&nbsp;</li>
    <li>#&nbsp;The&nbsp;format&nbsp;of&nbsp;the&nbsp;file&nbsp;is:&nbsp;/url=worker &nbsp;&nbsp;</li>
    <li>#&nbsp;/examples/*=loadbalancer &nbsp;&nbsp;</li>
    <li>JkMountFile&nbsp;conf/uriworkermap.properties&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>#&nbsp;Add&nbsp;shared&nbsp;memory. &nbsp;&nbsp;</li>
    <li>#&nbsp;This&nbsp;directive&nbsp;is&nbsp;present&nbsp;with&nbsp;1.2.10&nbsp;and &nbsp;&nbsp;</li>
    <li>#&nbsp;later&nbsp;versions&nbsp;of&nbsp;mod_jk,&nbsp;and&nbsp;is&nbsp;needed&nbsp;for&nbsp;&nbsp;</li>
    <li>#&nbsp;for&nbsp;load&nbsp;balancing&nbsp;to&nbsp;work&nbsp;properly &nbsp;&nbsp;</li>
    <li>JkShmFile&nbsp;logs/jk.shm&nbsp; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</li>
    <li>#&nbsp;Add&nbsp;jkstatus&nbsp;for&nbsp;managing&nbsp;runtime&nbsp;data &nbsp;&nbsp;</li>
    <li> &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;JkMount&nbsp;status &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;Order&nbsp;deny,allow &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;Deny&nbsp;from&nbsp;all &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;Allow&nbsp;from&nbsp;127.0.0.1&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
</pre>
<p>其中有两个设置是非常重要的：</p>
<div>
<ul type="disc">
    <li>
    <p><tt>LoadModule</tt> 指令必须引用下载的mod_jk库，路径中必须包括modules前缀。</p>
    </li>
    <li>
    <p><tt>JkMount
    指令通知Apache哪些URL应该被派发给mod_jk模块（也就是派发给Servlet容器）。上面的配置中，所有基于/application/*
    的请求都会派发给mod_jk负载平衡器。如果使用mod_jk作为一个专门的负载平衡器，可以将所有的请求(/*)派发给mod_jk。</tt></p>
    </li>
</ul>
</div>
<p>除了使用 <tt>JkMount</tt> 指令，也可以使用<tt>JkMountFile</tt> 指令指定一个配置文件，包含多个URL映射配置。你只需要在<tt>APACHE_HOME/conf</tt> 目录下创建一个<tt>uriworkermap.properties</tt> 文件。文件格式为<tt>/url=worker_name,示例文件如下：</tt></p>
<pre>
<div>java 代码</div>
<div>
<ol>
    <li>#&nbsp;Simple&nbsp;worker&nbsp;configuration&nbsp;file &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>#&nbsp;Mount&nbsp;the&nbsp;Servlet&nbsp;context&nbsp;to&nbsp;the&nbsp;ajp13&nbsp;worker &nbsp;&nbsp;</li>
    <li>/jmx-console=loadbalancer &nbsp;&nbsp;</li>
    <li>/jmx-console/*=loadbalancer &nbsp;&nbsp;</li>
    <li>/web-console=loadbalancer &nbsp;&nbsp;</li>
    <li>/web-console/*=loadbalancer &nbsp;&nbsp;</li>
</ol>
</div>
</pre>
<p>如上示例将配置 mod_jk 派发请求 <tt>/jmx-console</tt> 和<tt>/web-console</tt> 给Tomcat。</p>
</div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.5.3.&nbsp;在mod_jk中配置工作者节点</font></h3>
</div>
</div>
</div>
<p>接着需要创建conf/workers.properties文件，这个文件用来指定名个不同的Servlet容器的位置以及调用如何在这些容器之间进行平衡。针对一个两个节点的设置，示例文件如下：</p>
<pre>
<div>java 代码</div>
<div>
<ol>
    <li>#&nbsp;Define&nbsp;list&nbsp;of&nbsp;workers&nbsp;that&nbsp;will&nbsp;be&nbsp;used &nbsp;&nbsp;</li>
    <li>#&nbsp;for&nbsp;mapping&nbsp;requests &nbsp;&nbsp;</li>
    <li>worker.list=loadbalancer,status &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>#&nbsp;Define&nbsp;Node1 &nbsp;&nbsp;</li>
    <li>#&nbsp;modify&nbsp;the&nbsp;host&nbsp;as&nbsp;your&nbsp;host&nbsp;IP&nbsp;or&nbsp;DNS&nbsp;name. &nbsp;&nbsp;</li>
    <li>worker.node1.port=8009&nbsp;&nbsp;</li>
    <li>worker.node1.host=node1.mydomain.com&nbsp; &nbsp;&nbsp;</li>
    <li>worker.node1.type=ajp13 &nbsp;&nbsp;</li>
    <li>worker.node1.lbfactor=1&nbsp;&nbsp;</li>
    <li>worker.node1.cachesize=10&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>#&nbsp;Define&nbsp;Node2 &nbsp;&nbsp;</li>
    <li>#&nbsp;modify&nbsp;the&nbsp;host&nbsp;as&nbsp;your&nbsp;host&nbsp;IP&nbsp;or&nbsp;DNS&nbsp;name. &nbsp;&nbsp;</li>
    <li>worker.node2.port=8009&nbsp;&nbsp;</li>
    <li>worker.node2.host=&nbsp;node2.mydomain.com &nbsp;&nbsp;</li>
    <li>worker.node2.type=ajp13 &nbsp;&nbsp;</li>
    <li>worker.node2.lbfactor=1&nbsp;&nbsp;</li>
    <li>worker.node2.cachesize=10&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>#&nbsp;Load-balancing&nbsp;behaviour &nbsp;&nbsp;</li>
    <li>worker.loadbalancer.type=lb &nbsp;&nbsp;</li>
    <li>worker.loadbalancer.balance_workers=node1,node2 &nbsp;&nbsp;</li>
    <li>worker.loadbalancer.sticky_session=1&nbsp;&nbsp;</li>
    <li>#worker.list=loadbalancer &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>#&nbsp;Status&nbsp;worker&nbsp;for&nbsp;managing&nbsp;load&nbsp;balancer &nbsp;&nbsp;</li>
    <li>worker.status.type=status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
</pre>
<p>上述文件配置mod_jk执行Round-Robin的基于sticky-sessions的负载平衡策略，两个节点都监听8009端口。</p>
<p><tt>works.properties文件中，每个节点使用</tt><tt>worker.XXX</tt> 命名规范进行定义，这里 <tt>XXX</tt> 可以是任何名字，用来命名Servlet容器。对于每个工作者，必须指定在目标Servlet容器中配置的AJP13连接器的IP地址和端口号。</p>
<p><tt>lbfactor</tt> 属性用来表示负载平衡权重，决定节点之间的优先级，值越大，该节点将接受越多的请求。这个选项可以用来分配不同的节点不同的负载。</p>
<p><tt>cachesize</tt> 属性定义关联的Servlet容器的线程池大小，确定这个值没有超过Servlet容器在AJP13连接器中的配置。可以参考<a href="http://jakarta.apache.org/tomcat/connectors-doc/config/workers.html">jakarta.apache.org/tomcat/connectors-doc/config/workers.html </a></p>
<p><tt>conf/workers.properties</tt> 最后定义负载平衡工作者，唯一需要改变的是<tt>worker.loadbalancer.balanced_workers</tt> 设置，必须列出刚才定义的所有工作者。</p>
<p><tt>sticky_session</tt> 属性指定集群针对HTTP会话的处理方式，如果指定<tt>worker.loadbalancer.sticky_session=0，每个请求将在两个节点中进行负载平衡。但是当一个用户在某个节点创建一个会话时，比较好的方式是随后的请求都导向这个节点，这被称作</tt>"sticky session"，由于客户总是使用会话创建的节点服务所有随后的请求。否则用户的会话数据必须在两个节点进行同步，要启用"sticky session"，必须设置 <tt>worker.loadbalancer.sticky_session</tt> 值为1。</p>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>注意</h3>
<p>A non-loadbalanced setup with a single node required the <tt>worker.list=node1</tt> entry before mod_jk would function correctly.</p>
</div>
</div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.5.4.&nbsp;配置JBoss</font></h3>
</div>
</div>
</div>
<p>最后必须配置集群中所有节点的JBoss Tomcat实例。</p>
<p>在每个节点中，我们必须根据workers.properties文件中的worker名称来命名节点。比如，在JBoss 实例node1中，需要编辑<tt>JBOSS_HOME/server/all/deploy/jbossweb-tomcat50.sar/server.xml</tt> 文件，定位 元素添加一个jvmRoute属性：</p>
<div>
<div>
<div>xml 代码</div>
<div>
<ol>
    <li>&lt;Engine&nbsp;name="jboss.web"&nbsp;defaultHost="localhost"&nbsp;jvmRoute="node1"&gt;&nbsp;&nbsp; </li>
    <li>...&nbsp;... &nbsp;&nbsp; </li>
    <li>Engine&gt;&nbsp;&nbsp; </li>
</ol>
</div>
</div>
</div>
<span>
<p>然后，对于集群中的每一个节点，我们必须通知它添加一个jvmRoute值到会话cookies中，以便mod_jk可以路由随后的请求。编辑 <tt>JBOSS_HOME/server/all/deploy/jbossweb-tomcat50.sar/META-INF/jboss-service.xml</tt> 文件，定义UseJK的元素，设置值为true：</p>
<div>xml 代码</div>
<div>
<ol>
    <li>&lt;attribute&nbsp;name="UseJK"&gt;trueattribute&gt;&nbsp;&nbsp; </li>
</ol>
</div>
<p>到此为止，我们已经成功设置Apache_mod_jk使用sticky-session方式的负载平衡。</p>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>注意</h3>
<p>更多信息可以参考<tt><a href="http://wiki.jboss.org/wiki/Wiki.jsp?page=UsingMod_jk1.2WithJBoss">http://wiki.jboss.org/wiki/Wiki.jsp?page=UsingMod_jk1.2WithJBoss</a>。</tt></p>
</div>
</span></div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.5.5.&nbsp;配置HTTP会话状态复制</font></h3>
</div>
</div>
</div>
<p>目前为止，已经成功配置了sticky-session方式的负载平衡，但是这种方式并不是一个完善的解决方案，因为一个节点崩溃，所有的会话数据都会丢失。更可选的解决方式是在集群的节点之间复制会话状态，这样客户访问任一个节点都会获得同样的会话状态。</p>
<p><tt>jboss.cache:service=TomcatClusteringCache</tt> MBean 使用 JBoss Cache提供HTTP会话状态复制服务，这个MBean定义在<tt>deploy/tc5-cluster.sar/META-INF/jboss-service.xml</tt> 文件中。</p>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>注意</h3>
<p>JBoss AS 4.0.4 CR2以前的版本，HTTP会话缓存配置文件在<tt>deploy/tc5-cluster-service.xml文件中。</tt></p>
</div>
<p>下面是一个典型的<tt>deploy/tc5-cluster.sar/META-INF/jboss-service.xml</tt> 文件</p>
<div>
<div>xml 代码</div>
<div>
<ol>
    <li>&lt;mbean&nbsp;code="org.jboss.cache.aop.TreeCacheAop"&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;name="jboss.cache:service=TomcatClusteringCache"&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;depends&gt;jboss:service=Namingdepends&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;depends&gt;jboss:service=TransactionManagerdepends&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;depends&gt;jboss.aop:service=AspectDeployerdepends&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="TransactionManagerLookupClass"&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.jboss.cache.BatchModeTransactionManagerLookup &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;attribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="IsolationLevel"&gt;REPEATABLE_READattribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="CacheMode"&gt;REPL_ASYNCattribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="ClusterName"&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tomcat-${jboss.partition.name:Cluster} &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;attribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="UseMarshalling"&gt;falseattribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="InactiveOnStartup"&gt;falseattribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="ClusterConfig"&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;... &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;attribute&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;name="LockAcquisitionTimeout"&gt;15000attribute&gt;&nbsp;&nbsp; </li>
    <li>mbean&gt;&nbsp;&nbsp; </li>
</ol>
</div>
&nbsp;</div>
<span><span><span><span><span><span><span><span><span>
<p>详细的配置请参见JBossCache缓存配置部分，下面讨论几个比较关键的配置：</p>
<div>
<ul type="disc">
    <li>
    <p><strong>TransactionManagerLookupClass</strong> 设置事务管理器工厂，缺省值为<tt>org.jboss.cache.BatchModeTransactionManagerLookup，这个类通知缓存不要参与JTA事务，自己管理事务。</tt></p>
    </li>
    <li>
    <p><strong>IsolationLevel</strong> 设置更新分布式缓存的隔离级别，可选值包括：<tt>SERIALIZABLE</tt>, <tt>REPEATABLE_READ</tt>, <tt>READ_COMMITTED</tt>, <tt>READ_UNCOMMITTED</tt>, 和 <tt>NONE。</tt> 这里的隔离级别和数据库的隔离级别有同样的含义，对于大多数WEB应用程序来讲通常设置为<tt>REPEATABLE_READ</tt>。</p>
    </li>
    <li>
    <p><strong>CacheMode</strong> 控制缓存如何被复制。可选值包括：<tt>REPL_SYNC</tt> 和<tt>REPL_ASYNC，确定改变是应该同步还是异步复制。使用同步复制，确保在请求完成之前传播改变，同步复制相对来说会慢一些。</tt></p>
    </li>
    <li>
    <p><strong>ClusterName</strong> 指定集群名称。缺省的集群名称是由当前的JBoss分区名称加上"Tomcat-"前缀。所有的节点应该使用相同的集群名称。</p>
    </li>
    <li>
    <p><strong>UseMarshalling</strong> 和<strong>InactiveOnStartup</strong> 属性必须有相同的值，如果使用FIELD级别的会话复制，这两个值必须为true。</p>
    </li>
    <li>
    <p><strong>ClusterConfig</strong> 配置底层的JGoups 堆栈。最重要的配置元素是广播地址和端口号<tt>mcast_addr</tt> 和<tt>mcast_port，详细配置请参见JGroups配置。</tt></p>
    </li>
    <li>
    <p><strong>LockAcquisitionTimeout</strong> 设置获取锁的最大超时值，缺省值为15000。</p>
    </li>
    <li>
    <p><strong>UseReplQueue</strong> 使用异步复制时是否启动复制队列，这允许多个更新一起执行从而提升性能。复制队列属性由 <tt>ReplQueueInterval</tt> 和<tt>ReplQueueMaxElements</tt> 属性配置。</p>
    </li>
    <li>
    <p><strong>ReplQueueInterval</strong> 配置JBoss缓存处理复制队列的时间间隔。</p>
    </li>
    <li>
    <p><strong>ReplQueueMaxElements</strong>: 配置复制队列可以保存的最多的元素数目。</p>
    </li>
</ul>
</div>
</span></span></span></span></span></span></span></span></span></div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.5.6.&nbsp;在应用程序中启用会话复制</font></h3>
</div>
</div>
</div>
<p>要在你的WEB应用程序中启用集群，必须在web.xml文件中声明distributable。示例如下：</p>
<div>
<div>xml 代码</div>
<div>
<ol>
    <li>&nbsp;&nbsp; </li>
    <li><span>web-app&gt;&nbsp;&nbsp; </span></li>
</ol>
</div>
</div>
<pre> <br />
可以在jboss-web.xml文件中进一步配置会话复制，示例如下：<br />
<br />
<div>
<div>xml 代码</div>
<div>
<ol>
    <li>&lt;jboss-web&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;replication-config&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;replication-trigger&gt;SET_AND_NON_PRIMITIVE_GETreplication-trigger&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;replication-granularity&gt;SESSIONreplication-granularity&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;replication-field-batch-mode&gt;truereplication-field-batch-mode&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;replication-config&gt;&nbsp;&nbsp;</li>
    <li>jboss-web&gt;&nbsp;&nbsp;</li>
</ol>
</div>
</div>
<br />
</pre>
<p><tt>replication-trigger</tt> 元素确定什么情况触发一次会话复制，有四个选项：</p>
<div>
<ul type="disc">
    <li>
    <p><strong>SET</strong>: 使用此选项，一个会话只有在设置属性时才被认为需要复制。如果你的应用总是需要改变会话的属性，这个选项将是性能最优的。如果一个对象只是被检索和修改，但是不需要改写会话，这个对象的改变并不会造成会话复制。</p>
    </li>
    <li>
    <p><strong>SET_AND_GET</strong>: 使用此选项，任何属性的获取和设置都被认为需要复制。如果一个对象被检索和修改，但是不需要改定会话，这个对象的改变将会被复制。这个选项有显著的性能问题。</p>
    </li>
    <li>
    <p><strong>SET_AND_NON_PRIMITIVE_GET</strong>: 此选项类似于 SET_AND_GET，唯一的例外是只有非原始类型的检索操作被认为需要复制。比如，HTTP会话请求可以从属性中检索一个非原始类型的对象实例并更改，如果我们没有指定此选项，更改将不会被复制。这是缺省设置。</p>
    </li>
    <li>
    <p><strong>ACCESS</strong>: 使用此选项，只要会话被访问都被认为需要复制。由于每个HTTP请求都会造成会话被访问，所以每个请求都会导致会话复制。使用此选项，会话时间戳将在集群中同步。注意使用此选项会有显著的性能问题。</p>
    </li>
</ul>
</div>
<p><tt>replication-granularity</tt> 元素控制复制粒度，支持的选项包括：</p>
<div>
<ul type="disc">
    <li>
    <p><strong>SESSION</strong>: 基于会话的复制，只要会话发生改变，整个会话对象都会被序列化。</p>
    </li>
    <li>
    <p><strong>ATTRIBUTE</strong>: 基于属性的复制，复制只在属性被认为是脏的时候发生，比如lastAccessTime.。对于持有大量数据的会话，这个选项可以提升性能。</p>
    </li>
    <li>
    <p><strong>FIELD</strong>: 基于字段的复制，复制只在会话属性包含的对象的字段发生变化时发生。</p>
    </li>
</ul>
</div>
<p><tt>replication-field-batch-mode</tt> 表示是否需要在每个HTTP请求进行批量更新，缺省值为true。</p>
<p>如果你的会话通常比较小，SESSION选项比较适合，如果会话比较大，而且某些部分不是经常被访问，ATTRIBUTE 选项比较适合，如果会话属性包含大数据量的对象而且只有字段经常更改，FIELD 选项比较适合。</p>
</div>
<div>
<div>
<div>
<div>
<h3><font color="#0000ff">1.5.7.&nbsp;使用FIELD级别的复制</font></h3>
</div>
</div>
</div>
<p>FIELD-level replication only replicates modified data fields inside
objects stored in the session. It could potentially drastically reduce
the data traffic between clustered nodes, and hence improve the
performance of the whole cluster. To use FIELD-level replication, you
have to first prepare your Java class to indicate which fields are to
be replicated. This is done via JDK 1.4 style annotations embedded in
JavaDocs:</p>
<p>To annotate your POJO, we provide two annotations: <tt>@@org.jboss.web.tomcat.tc5.session.AopMarker</tt> and <tt>@@org.jboss.web.tomcat.tc5.session.InstanceAopMarker</tt>. When you annotate your class with <tt>AopMarker</tt>, you indicate that instances of this class will be used in FIELD-level replication. For exmaple,</p>
<pre>/*<br />
* My usual comments here first.<br />
* @@org.jboss.web.tomcat.tc5.session.AopMarker<br />
*/<br />
public class Address <br />
{<br />
...<br />
}<br />
</pre>
<p>If you annotate it with <tt>InstanceAopMarker</tt> instead, then all of its sub-class will be automatically annotated as well. For example,</p>
<pre>/*<br />
*<br />
* @@org.jboss.web.tomcat.tc5.session.InstanceOfAopMarker<br />
*/<br />
public class Person <br />
{<br />
...<br />
}<br />
</pre>
<p>then when you have a sub-class like</p>
<pre>public class Student extends Person<br />
{<br />
...<br />
}<br />
</pre>
<p>there will be no need to annotate <tt>Student</tt>. It will be annotated automatically because it is a sub-class of <tt>Person</tt>.</p>
<p>However, since we only support JDK 1.4 style annotation (provided by JBoss Aop) now, you will need to perform a pre-processing step. You need to use the JBoss AOP pre-compiler <tt>annotationc</tt> and post-compiler <tt>aopc</tt>
to process the above source code before and after they are compiled by
the Java compiler. Here is an example on how to invoke those commands
from command line.</p>
<pre>$ annotationc [classpath] [source files or directories]<br />
$ javac -cp [classpath] [source files or directories]<br />
$ aopc [classpath] [class files or directories]            <br />
</pre>
<p>Please see the JBoss AOP documentation for the usage of the pre- and post-compiler. The JBoss
AOP project also provides easy to use ANT tasks to help integrate those
steps into your application build process. In the next AS release, JDK
5.0 annotation support will be provided for greater transparency. But
for now, it is important that you perform the pre- and post-compilation
steps for your source code.</p>
<div style="margin-left: 0.5in; margin-right: 0.5in;">
<h3>Note</h3>
<p>Or, you can see a complete example on how to build, deploy, and
validate a FIELD-level replicated web application from this page: <tt>http://wiki.jboss.org/wiki/Wiki.jsp?page=Http_session_field_level_example</tt>. The example bundles the pre- and post-compile tools so you do not need to download JBoss AOP separately.</p>
</div>
<p>When you deploy the web application into JBoss AS, make sure that the following configurations are correct:</p>
<div>
<ul type="disc">
    <li>
    <p>In the server's <tt>deploy/tc5-cluster.sar/META-INF/jboss-service.xml</tt> file, the <tt>inactiveOnStartup</tt> and <tt>useMarshalling</tt> attributes must both be <tt>true</tt>.</p>
    </li>
    <li>
    <p>In the application's <tt>jboss-web.xml</tt> file, the <tt>replication-granularity</tt> attribute must be <tt>FIELD</tt>.</p>
    </li>
</ul>
</div>
<p>Finally, let's see an example on how to use FIELD-level replication on those data classes. Notice that there is no need to call <tt>session.setAttribute()</tt> after you make changes to the data object, and all changes to the fields are automatically replicated across the cluster.</p>
&lt;pre class="programlistin</div>
</div>
</div>
</div>
</div>
<img src ="http://www.blogjava.net/libin2722/aggbug/222953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-08-19 11:18 <a href="http://www.blogjava.net/libin2722/articles/222953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>