先介绍一下项目系统的环境,Liferay Version: 5.2.2
两台硬件服务器,一台WINXP(M1),一台linux(M2),用Virtualbox在M2上虚拟了两个linux分别叫M3,M4
DB Mysql: JCR(JackRabbit DB), Portal(Liferay DB) 放在M1上
Web Server: Solr Server 搜索引擎Server在M1上
Liferay Tomcat 两个,分别放在M3,M4
Http Server: Apache Server 2.2.14 放在M2
Liferay的集群配置其实在他的liferay-administration-guide文档第五章,对性能优化也有介绍,附件是在网上找的一个翻译好的中文文档,写的很不错
然后还参照了Lifreay官方网站Wiki上面的一些文章,[url]http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Clustering [/url]
文档里有的部分我就不说了,说一下他没有提到的地方
一、JackRibbit集群按文档上做,然后在portal-ext.properties里面加上下面代码:
######################jackrabbit configuration###################################
dl.hook.impl=com.liferay.documentlibrary.util.JCRHook
二、Solr配置的时候也没有问题,但是在search user & document会报错,解决方案如下
修改com.liferay.portal.search.lucene.LuceneUtil的addRequiredTerm如下:
public static void addRequiredTerm(
BooleanQuery booleanQuery, String field, String value, boolean like) {
if (like) {
/*
* cjackson: Made this change based on Liferay bug report for searching
* users in control panel with Solr.
*
* http://issues.liferay.com/browse/LPS-3120
*
* This had to be made in addition to the other change on line 285 below
* because I noticed the Advanced search was still having problems.
*/
if( value.startsWith("%") )
value = value.substring(1);
/* End cjackson modifications */
value = StringUtil.replace(
value, StringPool.PERCENT, StringPool.STAR);
value = value.toLowerCase();
WildcardQuery wildcardQuery = new WildcardQuery(
new Term(field, value));
booleanQuery.add(wildcardQuery, BooleanClause.Occur.MUST);
}
else {
//text = KeywordsUtil.escape(value);
Term term = new Term(field, value);
TermQuery termQuery = new TermQuery(term);
booleanQuery.add(termQuery, BooleanClause.Occur.MUST);
}
}
三、Cache方面在portal-ext.properties加上如下代码:
##########################hibernate configuration#############################
net.sf.ehcache.configurationResourceName=/myehcache/hibernate-clustered.xml
##########################ehcache configuration#############################
ehcache.multi.vm.config.location=/myehcache/liferay-multi-vm-clustered.xml
ehcache.single.vm.config.location=/myehcache/liferay-single-vm.xml
记得把cache下面对应的这三个文件copy到web-inf/classes/myehcache下面,然后修改三个文件中cache的过期时间和空亲时间,因为liferay全写的是600s,你会发现在一台server上面修改了,其他的server一点反应也没有,这个值要改成多少,你需要考虑系统性能而定。
四、Http Server负载均衡配置,apache我选的是2.0以后版本,因为他已集成了mod_jk.so的功能。只需简单的把下面几行去掉注释,就相当于以前用mod_jk.so比较繁琐的配置了,修改httped.conf:
去掉下面几句的注释
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Include conf/extra/httpd-vhosts.conf
最下面加上如下代码,
ProxyRequests Off
<proxy balancer://lfcluster>
BalancerMember ajp://192.168.52.116:8009 loadfactor=1 route=jvm1
BalancerMember ajp://192.168.52.103:8009 loadfactor=1 route=jvm2
#BalancerMember ajp://127.0.0.1:9001 loadfactor=1 route=jvm3
#BalancerMember ajp://127.0.0.1:9003 loadfactor=1 route=jvm4
</proxy>
IP和端口修改成自已的
然后打开httpd-vhosts.conf 修改如下:
<VirtualHost *:80>
ServerAdmin admin@**********.com
ServerName localhost
ServerAlias localhost
ProxyPass / balancer://lfcluster/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse / balancer://lfcluster/
</VirtualHost>
虚拟主机更详细的配置你可以参考apache网站
五、Tomcat 集群配置
打开Server.xml,shutdown, ajp, http这三个端口就不多说了,解开下面注释
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
jvmRoute的值要根据apache的配置,不能冲突。
接着是最重要的一点,tomcat默认集群配置(<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>)时,配置的细节实际上被省略了,对于大多数应用而言,使用默认配置已经足够,完整的默认配置应该是这样:
<!--同步异步模式由channelSendOptions参数控制,默认值是8,为异步模式,4是同步模式。在异步模式下,可以通过加上拷贝确认(Acknowledge)来提高可靠性,此时channelSendOptions设为10。-->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="6">
<!---session 拷贝方式 BackupManager 只拷贝部署当前应用的服务器,DeltaManager 拷贝方式all to all-->
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<!--
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
-->
<!--Channel负责对tomcat集群的IO层进行配置-->
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<!--Membership用于发现集群中的其他节点,这里的address用的是组播地址(Multicast address,了解更多组播地址详情请参见http://zyycaesar.iteye.com/admin/blogs/296501),使用同一个组播地址和端口的多个节点同属一个子集群,因此通过自定义组播地址和端口就可将一个大的tomcat集群分成多个子集群-->
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<!--Receiver用于各个节点接收其他节点发送的数据,在默认配置下tomcat会从4000-4100间依次选取一个可用的端口进行接收,自定义配置时,如果多个tomcat节点在一台物理服务器上注意要使用不同的端口-->
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="5001"
selectorTimeout="100"
maxThreads="6"/>
<!--Sender用于向其他节点发送数据,具体实现通过Transport配置,PooledParallelSender是从tcp连接池中获取连接,可以实现并行发送,即集群中的多个节点可以同时向其他所有节点发送数据而互不影响-->
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<!---Interceptor有点类似下面将要解释的Valve,起到一个阀门的作用,在数据到达目的节点前进行检测或其他操作,如TcpFailureDetector用于检测在数据的传输过程中是否发生了tcp错误。--->
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
<!--Valve用于在节点向客户端响应前进行检测或进行某些操作,ReplicationValve就是用于用于检测当前的响应是否涉及Session数据的更新,如果是则启动Session拷贝操作,filter用于过滤请求,如客户端对图片,css,js的请求就不会涉及Session,因此不需检测,默认状态下不进行过滤,监测所有的响应.JvmRouteBinderValve会在前端的Apache mod_jk发生错误时保证同一客户端的请求发送到集群的同一个节点-->
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<!--Deployer用于集群的farm功能,监控应用中文件的更新,以保证集群中所有节点应用的一致性,如某个用户上传文件到集群中某个节点的应用程序目录下,Deployer会监测到这一操作并把这一文件拷贝到集群中其他节点相同应用的对应目录下以保持所有应用的一致。这是一个相当强大的功能,不过很遗憾,tomcat集群目前并不能做到这一点,开发人员正在努力实现它,这里的配置只是预留了一个接口-->
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<!--Listener用于跟踪集群中节点发出和收到的数据,也有点类似Valve的功能。-->
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
最后在Web.xml里面加上<distributable/>,官方文档没有这个,但我觉得还是应该加上,因为按照标准的tomcat启动,当Host对象被创建时,一个Cluster对象(默认配置下是SimpleTcpCluster)也同时被关联到这个Host对象。当某个应用在web.xml中设置了distributable时,Tomcat将为此应用的上下文环境创建一个DeltaManager。SimpleTcpCluster启动membership服务和Replication服务。