Tomcat集群+Apache的实现css
tomcat集群各节点经过创建tcp连接来完成Session的拷贝,拷贝有同步和异步两种模式。在同步模式下,对客户端的响应必须在Session拷贝到其余节点完成后进行;异步模式无需等待Session拷贝完成就可响应。异步模式更高效,可是同步模式可靠性更高。同步异步模式由channelSendOptions参数控制,默认值是8,为异步模式,4是同步模式。在异步模式下,能够经过加上拷贝确认(Acknowledge)来提升可靠性,此时channelSendOptions设为10。
Manager用来在节点间拷贝Session,默认使用DeltaManager,DeltaManager采用的一种all-to-all的工做方式,即集群中的节点会把Session数据向全部其余节点拷贝,而无论其余节点是否部署了当前应用。当集群中的节点数量不少而且部署着不一样应用时,可使用BackupManager,BackManager仅向部署了当前应用的节点拷贝Session。可是到目前为止BackupManager并未通过大规模测试,可靠性不及DeltaManager。
Channel负责对tomcat集群的IO层进行配置。Membership用于发现集群中的其余节点,这里的address用的是组播地址, 使用同一个组播地址和端口的多个节点同属一个子集群,所以经过自定义组播地址和端口就可将一个大的tomcat集群分红多个子集群。Receiver用于各个节点接收其余节点发送的数据,在默认配置下tomcat会从4000-4100间依次选取一个可用的端口进行接收,自定义配置时,若是多个tomcat节点在一台物理服务器上注意要使用不一样的端口。Sender用于向其余节点发送数据,具体实现经过Transport配置,PooledParallelSender是从tcp链接池中获取链接,能够实现并行发送,即集群中的多个节点能够同时向其余全部节点发送数据而互不影响。Interceptor有点相似下面将要解释的Valve,起到一个阀门的做用,在数据到达目的节点前进行检测或其余操做,如TcpFailureDetector用于检测在数据的传输过程当中是否发生了tcp错误。关于Channel的编程模型,请参见
http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/tribes/Channel.html。
Valve用于在节点向客户端响应前进行检测或进行某些操做,ReplicationValve就是用于用于检测当前的响应是否涉及Session数据的更新,若是是则启动Session拷贝操做,filter用于过滤请求,如客户端对图片,css,js的请求就不会涉及Session,所以不需检测,默认状态下不进行过滤,监测全部的响应。JvmRouteBinderValve会在前端的Apache mod_jk发生错误时保证同一客户端的请求发送到集群的同一个节点,tomcat官方文档并未解释如何实现这一点,并且笔者认为这一设置彷佛并没有多大实用性。
Deployer用于集群的farm功能,监控应用中文件的更新,以保证集群中全部节点应用的一致性,如某个用户上传文件到集群中某个节点的应用程序目录下,Deployer会监测到这一操做并把这一文件拷贝到集群中其余节点相同应用的对应目录下以保持全部应用的一致。这是一个至关强大的功能,不过很遗憾,tomcat集群目前并不能作到这一点,开发人员正在努力实现它,这里的配置只是预留了一个接口。
Listener用于跟踪集群中节点发出和收到的数据,也有点相似Valve的功能。
第一部分
tomcat
配置
(ver 6.0.18)
在大致了解了tomcat集群实现模型后,就能够对集群做出更优化的配置了,tomcat推荐了一套配置,使用了比DeltaManager更高效的BackupManager,而且对ReplicationValve设置了请求过滤,注意在一台服务器部署多个节点时须要修改Receiver的侦听端口,另外,为了更高效的在节点间拷贝数据,全部tomcat节点最好采用相同的配置,server.xml cluster部分配置具体配置以下
DeltaManager
方式配置集群和组播
, Receiver prot
范围配置为
4000-4100
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
bind="192.168.1.184" #绑定网络接口
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto" #tomcat 不在同一台机器上,要将auto改成对外网络接口IP
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
BackupManager
方式配置集群和组播
,Receiver prot
范围未规定
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="6">
<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 className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="5000"
selectorTimeout="100"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<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 className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/-->
<!--Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/-->
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
说明:1. jvmRoute=“xxx” 要启用,与apache 集群配置中用到的名称一致。
2. 要在web.xml的display-name后面 下加上<distributable/>标签。
3. 如在一台主机上多个tomcat 节点要确认每一个Receiver prot的惟一性。
4. linux 环境下要开启组播,命令route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0。
5. 以上两中配置方法都实用。
第二部分
apache
配置
(ver 2.2.3)
在Apache 2.2版本以前,通常有mod_jk2和mod_jk两个模块可供选择,mod_jk2模块是比较早的一种链接器,在动、静页面过滤上可使用正则表达式,所以使用配置灵活。可是mod_jk2模块如今已经没有开发人员支持了,版本更新也就此中止。继承jk2模块的是mod_jk模块,mod_jk模块支持Apache 1.x和2.X系列版本,如今通常都使用mod_jk作Apache和Tomcat的链接器。
在Apache 2.2版本之后,又出现了两种链接器可供选择,就是http-proxy和proxy-ajp模块。Apache的proxy(代理)模块能够实现双向代理,功能很是强大,从链接器的实现原理看,用http-proxy模块实现也是很天然的事情,只需打开Tomcat的http功能,而后用Apache的proxy代理功能将动态请求交给Tomcat处理,而静态数据交给Apache自身就能够了。proxy-ajp模块是专门为Tomcat整合所开发的,经过ajp协议专门代理对Tomcat的请求。根据官方的测试,proxy-ajp的执行效率要比http-proxy高,所以在Apache 2.2之后的版本,用proxy-ajp模块做为Apache和Tomcat的链接器是个不错的选择。
A: Apache
采用
ajp
方式链接
tomcat
1. apache 采用系统默认安装和编译安装均可以,apache 2.2后版本默认安装都支持mod_proxy mod_proxy_ajp mod_proxy_http mod_proxy_balancer mod_proxy_connect等模块,只要确认httpd.conf 配置中未注释便可(默认安装后所有模块支持都已打开,以下:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.
2.在/etc/http/conf.d 下新增虚拟主机文件proxy_ajp.conf(有些版本系统自带,内容以下)
<VirtualHost *:80>
ServerAdmin admin@coob.cn
DocumentRoot /home/gov/www/fg_gov/root
DirectoryIndex index.shtml
ServerName node2.12398.gov.cn
ErrorLog logs/gov.error_log
CustomLog logs/dummy-host.example.com-access_log common
#################目录权限配置###############
<Directory "/home/gov/www/fg_gov/root">
Options Indexes FollowSymLinks Includes
AllowOverride None
Order allow,deny
Allow from all
</Directory>
#################代理配置,静态对象由apache处理###############
ProxyRequests Off
ProxyPass /p_w_picpaths !
ProxyPass /pic !
ProxyPass /js !
ProxyPass /css !
ProxyPass /html !
ProxyPass /index.shtml !
#################集群配置###############
ProxyPass / balancer://fg_gov/ stickysession=JSESSIONID|jsessionid nofailover=Off
ProxyPa***everse / balancer://fg_gov/
#ProxyPass / balancer://fg_gov/ stickysession=jsessionid nofailover=On
<Proxy balancer://fg_gov>
BalancerMember ajp://127.0.0.1:5109 loadfactor=1 route=s1
BalancerMember ajp://127.0.0.1:6109 loadfactor=1 route=s2
</Proxy>
</VirtualHost>
说明:stickysession=jsessionid nofailover=On(点开每一个页面都轮循)
stickysession=JSESSIONID|jsessionid nofailover=Off(关闭浏览器后才轮循)
B:
采用
mod_jk
方式链接
tomcat
1. 在/etc/httpd/conf.d/目录下新增mod_jk.conf workers.properties文件,
[root@node conf]# cat mod_jk.conf
LoadModule jk_module modules/mod_jk.so
JkWorkersFile "conf.d/workers.properties"
JkLogLevel info
JKLogFile "logs/mod_jk.log"
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkRequestLogFormat "%w %V %T"
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin admin@coob.cn
DocumentRoot /home/gov/www/fg_gov/root
Alias /login "/home/gov/www/bg_gov/root"
Alias /admin "/home/gov/www/admin_gov/root"
DirectoryIndex index.shtml index.jsp
ServerName node2.12398.gov.cn
ErrorLog logs/gov.error_log
CustomLog logs/dummy-host.example.com-access_log common
#################目录权限配置###############
<Directory "/home/gov/www/fg_gov/root">
Options FollowSymLinks Includes
AllowOverride None
Order allow,deny
Allow from all
</Directory>
JkMount /jkstatus status
JkMount /* loadbalancer
JkUnmount /*.jpg loadbalancer
JkUnmount /*.css loadbalancer
JkUnMount /*.gif loadbalancer
JkUnMount /*.png loadbalancer
JkUnmount /*.js loadbalancer
JkUnmount /*.html loadbalancer
JkUnmount /*.htm loadbalancer
JkUnmount /*.shtml loadbalancer
JkUnmount /*.swf loadbalancer
JkUnmount /*.flv loadbalancer
JkUnmount /*.xml loadbalancer
JkUnmount /*.ico loadbalancer
</VirtualHost>
说明:JkMount和JkUnmount的写法
JkMount把匹配的转发到指定服务器.
JkUnMount把匹配的不转发到指定服务器.
JkUnMount
选项的级别高于JkMount.
单独有JkMount规则有效,但
单独有
JkUnMount
无效,JkUnMount与JkMount要成对出现.
[root@node conf.d]# cat workers.properties
########worker list#################
worker.list=loadbalancer,status
############server名为s1############
worker.s1.port=5109
worker.s1.host=localhost
worker.s1.type=ajp13
worker.s1.lbfactor=50
worker.s1.socket_timeout=300
worker.s1.cache_timeout=750
worker.s1.socket_keepalive=1
worker.s1.redirect=s2
#worker.s1.fail_on_status=-500,-503,404
############server名为s2#############
worker.s2.port=6109
worker.s2.host=localhost
worker.s2.type=ajp13
worker.s2.lbfactor=50
worker.s2.socket_timeout=300
worker.s2.cache_timeout=750
worker.s2.socket_keepalive=1
worker.s2.redirect=s1
#worker.s1.fail_on_status=500,503,-404
############oadbalancer负载均衡########
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=s1,s2
worker.loadbalancer.sticky_session=1
#worker.loadbalancer.sticky_session_force=1
worker.status.type=status
说明:
若是要想改变apache 和tomcat处理的静态元素,不重启apache就生效的话,能够在mod_jk.conf中使用JkWorkFile “conf.d/uriworkermap.properties”参数,这时需在/conf.d下新增uriworkermap.properties文件,就能够把上述文件中的JkMount 和JkUnmout 单独写入这个文件中,写法要用apache 官方文档中的另一种写法(这是可取消上文中的JkMount JkUnMout部分,文件内容以下
[root@node httpd]# cat /etc/httpd/conf.d/uriworkermap.properties
/*=loadbalancer
ps=/
/jkstatus=status
!/*.gif=loadbalancer
!/*.jpg=loadbalancer
!/*.png=loadbalancer
!/*.css=loadbalancer
!/*.js=loadbalancer
!/*.htm=loadbalancer
!/*.html=loadbalancer
!/*.shtml=loadbalancer
!/*.swf=loadbalancer
!/*.flv=loadbalancer
!/*.xml=loadbalancer
!/*.ico=loadbalancer