一、apache代理tomcat
上篇博文已经学习了nginx代理和负载均衡tomcat及apache基于mod_proxy模块代理tomcat;
现在来学习下apache基于mod_jk模块实现代理及负载均衡Tomcat Cluster
1、基于httpd代理tomcat时可以使用httpd的两个模块
1)mod_jk:第三方模块
mod_jk是ASF的一个项目,是一个工作于apache端基于AJP协议与Tomcat通信的连接器,它是apache的一个模块,是AJP协议的客户端(服务端是Tomcat的AJP连接器)。
后端tomcat使用的连接器:tomcat ajp
2)mod_proxy:标配模块
mod_proxy_http
mod_proxy_ajp
mod_proxy_balancer:负载均衡
后端tomcat使用的连接器:mod_porxy_http: tomcat http,mod_proxy_ajp: tomcat ajp
二、httpd基于jk_module模块代理tomcat
1、环境
客户端:Windows 192.168.200.88
node5: CentOS6.7-x86_64 eth0:192.168.100.175 eth1:192.168.200.175 httpd
node6:CentOS6.5-x86_64 eth0:192.168.200.179 tomcat1
node7:CentOS6.5-x86_64 eth0:192.168.200.180 tomcat2
拓扑图就不画了,很简单的
2、先部署后端node7上的TomcatB
注意:为了安全考虑不应该使用root用户运行tomcat,应该把tomcat的文件修改成普通用户tomcat,并切换至tomcat用户再启动tomcat,
1)安装jdk
[root@BAIYU_180 src]# ls apache-tomcat-8.0.29.tar.gz jdk-8u65-linux-x64.tar.gz [root@BAIYU_180 src]# tar xf jdk-8u65-linux-x64.tar.gz -C /usr/local [root@BAIYU_180 src]# ls /usr/local/jdk1.8.0_65/ bin include lib README.html THIRDPARTYLICENSEREADME-JAVAFX.txt COPYRIGHT javafx-src.zip LICENSE release THIRDPARTYLICENSEREADME.txt db jre man src.zip [root@BAIYU_180 src]# ln -sv /usr/local/jdk1.8.0_65 /usr/local/jdk "/usr/local/jdk" -> "/usr/local/jdk1.8.0_65" [root@BAIYU_180 src]# ls /usr/local/jdk bin include lib README.html THIRDPARTYLICENSEREADME-JAVAFX.txt COPYRIGHT javafx-src.zip LICENSE release THIRDPARTYLICENSEREADME.txt db jre man src.zip
添加环境变量
[root@BAIYU_180 src]# vi /etc/profile.d/java.sh 1 export JAVA_HOME=/usr/local/jdk 2 export PATH=$JAVA_HOME/bin:$PATH [root@BAIYU_180 src]# . /etc/profile.d/java.sh [root@BAIYU_180 src]# java -version #安装成功 java version "1.8.0_65" Java(TM) SE Runtime Environment (build 1.8.0_65-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
2)安装tomcat
[root@BAIYU_180 src]# ls apache-tomcat-8.0.29.tar.gz jdk-8u65-linux-x64.tar.gz [root@BAIYU_180 src]# tar xf apache-tomcat-8.0.29.tar.gz -C /usr/local [root@BAIYU_180 src]# ls /usr/local/apache-tomcat-8.0.29/ bin lib logs RELEASE-NOTES temp work conf LICENSE NOTICE RUNNING.txt webapps [root@BAIYU_180 src]# ln -sv /usr/local/apache-tomcat-8.0.29/ /usr/local/tomcat "/usr/local/tomcat" -> "/usr/local/apache-tomcat-8.0.29/" [root@BAIYU_180 src]# ls /usr/local/tomcat bin lib logs RELEASE-NOTES temp work conf LICENSE NOTICE RUNNING.txt webapps
添加环境变量
[root@BAIYU_180 src]# ls apache-tomcat-8.0.29.tar.gz jdk-8u65-linux-x64.tar.gz [root@BAIYU_180 src]# tar xf apache-tomcat-8.0.29.tar.gz -C /usr/local [root@BAIYU_180 src]# ls /usr/local/apache-tomcat-8.0.29/ bin lib logs RELEASE-NOTES temp work conf LICENSE NOTICE RUNNING.txt webapps [root@BAIYU_180 src]# ln -sv /usr/local/apache-tomcat-8.0.29/ /usr/local/tomcat "/usr/local/tomcat" -> "/usr/local/apache-tomcat-8.0.29/" [root@BAIYU_180 src]# ls /usr/local/tomcat bin lib logs RELEASE-NOTES temp work conf LICENSE NOTICE RUNNING.txt webapps [root@BAIYU_180 src]# vi /etc/profile.d/tomcat.sh 1 export CATALINA_HOME=/usr/local/tomcat 2 export PATH=$CATALINA_HOME/bin:$PATH [root@BAIYU_180 src]# . /etc/profile.d/tomcat.sh [root@BAIYU_180 src]# catalina.sh -h Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr/local/jdk Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Usage: catalina.sh ( commands ... ) commands: debug Start Catalina in a debugger debug -security Debug Catalina with a security manager jpda start Start Catalina under JPDA debugger run Start Catalina in the current window run -security Start in the current window with security manager start Start Catalina in a separate window start -security Start in a separate window with security manager stop Stop Catalina, waiting up to 5 seconds for the process to end stop n Stop Catalina, waiting up to n seconds for the process to end stop -force Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running stop n -force Stop Catalina, wait up to n seconds and then use kill -KILL if still running configtest Run a basic syntax check on server.xml - check exit code for result version What version of tomcat are you running? Note: Waiting for the process to end and use of the -force option require that $CATALINA_PID is defined [root@BAIYU_180 src]# catalina.sh version #安装成功 Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr/local/jdk Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Server version: Apache Tomcat/8.0.29 Server built: Nov 20 2015 09:18:00 UTC Server number: 8.0.29.0 OS Name: Linux OS Version: 2.6.32-431.el6.x86_64 Architecture: amd64 JVM Version: 1.8.0_65-b17 JVM Vendor: Oracle Corporation
3)创建系统用户tomcat运行tomcat
[root@BAIYU_180 src]# useradd -r tomcat [root@BAIYU_180 src]# cd /usr/local/tomcat/ [root@BAIYU_180 tomcat]# ll 总用量 112 drwxr-xr-x 2 root root 4096 11月 29 12:42 bin drwxr-xr-x 2 root root 4096 11月 20 17:20 conf drwxr-xr-x 2 root root 4096 11月 29 12:42 lib -rw-r--r-- 1 root root 57011 11月 20 17:20 LICENSE drwxr-xr-x 2 root root 4096 11月 20 17:18 logs -rw-r--r-- 1 root root 1444 11月 20 17:20 NOTICE -rw-r--r-- 1 root root 6741 11月 20 17:20 RELEASE-NOTES -rw-r--r-- 1 root root 16195 11月 20 17:20 RUNNING.txt drwxr-xr-x 2 root root 4096 11月 29 12:42 temp drwxr-xr-x 7 root root 4096 11月 20 17:19 webapps drwxr-xr-x 2 root root 4096 11月 20 17:18 work [root@BAIYU_180 tomcat]# chown -R tomcat.tomcat . [root@BAIYU_180 tomcat]# ll 总用量 112 drwxr-xr-x 2 tomcat tomcat 4096 11月 29 12:42 bin drwxr-xr-x 2 tomcat tomcat 4096 11月 20 17:20 conf drwxr-xr-x 2 tomcat tomcat 4096 11月 29 12:42 lib -rw-r--r-- 1 tomcat tomcat 57011 11月 20 17:20 LICENSE drwxr-xr-x 2 tomcat tomcat 4096 11月 20 17:18 logs -rw-r--r-- 1 tomcat tomcat 1444 11月 20 17:20 NOTICE -rw-r--r-- 1 tomcat tomcat 6741 11月 20 17:20 RELEASE-NOTES -rw-r--r-- 1 tomcat tomcat 16195 11月 20 17:20 RUNNING.txt drwxr-xr-x 2 tomcat tomcat 4096 11月 29 12:42 temp drwxr-xr-x 7 tomcat tomcat 4096 11月 20 17:19 webapps drwxr-xr-x 2 tomcat tomcat 4096 11月 20 17:18 work [root@BAIYU_180 tomcat]# su - tomcat -bash-4.1$ catalina.sh start Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr/local/jdk Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Tomcat started.
测试:
4)再添加一个测试页面
[root@BAIYU_180 ~]# cd /usr/local/tomcat/ [root@BAIYU_180 tomcat]# ls bin conf lib LICENSE logs NOTICE RELEASE-NOTES RUNNING.txt temp webapps work [root@BAIYU_180 webapps]# mkdir -pv testapp/{classes,lib,WEB-INF,META-INF} mkdir: 已创建目录 "testapp" mkdir: 已创建目录 "testapp/classes" mkdir: 已创建目录 "testapp/lib" mkdir: 已创建目录 "testapp/WEB-INF" mkdir: 已创建目录 "testapp/META-INF" [root@BAIYU_180 webapps]# vi testapp/index.jsp 1 <%@ page language="java" %> 2 <html> 3 <head><title>TomcatB</title></head> 4 <body> 5 <h1><font color="blue">TomcatB.magedu.com</font></h1> 6 <table align="centre" border="1"> 7 <tr> 8 <td>Session ID</td> 9 <% session.setAttribute("magedu.com","magedu.com"); %> 10 <td><%= session.getId() %></td> 11 </tr> 12 <tr> 13 <td>Created on</td> 14 <td><%= session.getCreationTime() %></td> 15 </tr> 16 </table> 17 </body> 18 </html>
测试:
3、安装httpd并添加jk_module模块
1)安装httpd
[root@BAIYU_175 ~]# yum install httpd httpd-devel -y #直接Yum安装了 [root@BAIYU_175 ~]# service httpd start [root@BAIYU_175 ~]# httpd -M|grep jk #默认没有安装mod_jk模块 httpd: apr_sockaddr_info_get() failed for BAIYU_175 httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName Syntax OK
测试:
2)安装jk_module模块
[root@BAIYU_175 ~]# ls anaconda-ks.cfg install.log.syslog trash.sh install.log tomcat-connectors-1.2.40-src.tar.gz [root@BAIYU_175 ~]# tar xf tomcat-connectors-1.2.40-src.tar.gz [root@BAIYU_175 ~]# cd tomcat-connectors-1.2.40-src [root@BAIYU_175 tomcat-connectors-1.2.40-src]# ls conf HOWTO-RELEASE.txt LICENSE NOTICE support xdocs docs jkstatus native README.txt tools [root@BAIYU_175 tomcat-connectors-1.2.40-src]# cd native/ #native目录是要使用的连接器 [root@BAIYU_175 native]# ls aclocal.m4 buildconf.sh configure iis netscape STATUS.txt apache-1.3 BUILDING.txt configure.ac Makefile.am README.txt TODO.txt apache-2.0 common docs Makefile.in scripts [root@BAIYU_175 native]# less README.txt #查看给的安装提示 #看到其中有这么2行 How do i build it? ------------------ Just take a look at BUILDING.txt [root@BAIYU_175 native]# ls aclocal.m4 buildconf.sh configure iis netscape STATUS.txt apache-1.3 BUILDING.txt configure.ac Makefile.am README.txt TODO.txt apache-2.0 common docs Makefile.in scripts [root@BAIYU_175 native]# less BUILDING.txt #看到如下行 General Build Instructions ========================== To build tomcat-connectors you need to run "configure" and "make": ./configure [autoconf arguments] [tomcat-connectors arguments] make It is possible to set CFLAGS and LDFLAGS to add some platform specifics: LDFLAGS=-lc \ ./configure --with-apxs=/home2/local/apache/bin/apxs [root@BAIYU_175 native]# which apxs #查看本机apxs命令的安装位置 /usr/sbin/apxs [root@BAIYU_175 native]# ./configure --with-apxs=/usr/sbin/apxs [root@BAIYU_175 native]# make && make install [root@BAIYU_175 native]# ls /usr/lib64/httpd/modules/mod_jk.so #确认一下 /usr/lib64/httpd/modules/mod_jk.so
3)修改httpd配置文件装载jk_module模块
[root@BAIYU_175 native]# cd /etc/httpd/conf.d/ [root@BAIYU_175 conf.d]# ls README welcome.conf [root@BAIYU_175 conf.d]# vi mod_jd.conf #这里使用一个专门的配置文件来保存相关指令及其设置。其内容如下: 1 LoadModule jk_module modules/mod_jk.so 2 JkWorkersFile /etc/httpd/conf.d/workers.properties #指定后端tomcat配置文件,随便 取名,不要以.cnf结尾即可 3 JkLogFile logs/mod_jk.log #jk_modules的日志 4 JkLogLevel info 5 JkMount /status ! #此路径不代理 6 JkMount /* TomcatB #/下内容全部代理至TomcatB 7 JkMount /status StatA #此路径由StatA响应,jk_modules自己提供 [root@BAIYU_175 conf.d]# vi /etc/httpd/conf.d/workers.properties 1 worker.list=TomcatB,StatA 2 worker.TomcatB.host=192.168.200.180 3 worker.TomcatB.port=8009 4 worker.TomcatB.type=ajp13 5 worker.StatA.type=status [root@BAIYU_175 conf.d]# service httpd configtest httpd: apr_sockaddr_info_get() failed for BAIYU_175 httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName Syntax OK [root@BAIYU_175 conf.d]# service httpd reload 重新载入 httpd: [root@BAIYU_175 conf.d]# httpd -M|grep jk httpd: apr_sockaddr_info_get() failed for BAIYU_175 httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName jk_module (shared) Syntax OK
测试:从浏览器访问192.168.200.175
除了需要使用LoadModule指令在apache中装载模块外,mod_jk还需要在apache的主配置文件中设置其它一些指令来配置其工作属。如JkWorkersFile则用于指定保存了worker相关工作属性定义的配置文件,JkLogFile则用于指定mod_jk模块的日志文件,JkLogLevel则可用于指定日志的级别(info, error, debug),此外还可以使用JkRequestLogFormat自定义日志信息格式。而JkMount(格式: JkMount <URL to match> <Tomcat worker name>)指定则用于控制URL与Tomcat workers的对应关系。
对于apache代理来说,每一个后端的Tomcat实例中的engine都可以视作一个worker,而每一个worker的地址、连接器的端口等信息都需要在apache端指定以便apache可以识别并使用这些worker。约定俗成,配置这些信息的文件通常为workers.properties,其具体路径则是使用前面介绍过的JkWorkersFile指定的,在apache启动时,mod_jk会扫描此文件获取每一个worker的配置信息。比如,我们这里使用/etc/httpd/conf.d/workers.properties。
workers.properties文件一般由两类指令组成:
一是mod_jk可以连接的各worker名称列表,
二是每一个worker的属性配置信息。它们分别遵循如下使用语法。
worker.list = < a comma separated list of worker names >
worker. <worker name> .<property> = <property value>
其中worker.list指令可以重复指定多次,而worker name则是Tomcat中engine组件jvmRoute参数的值。如:
worker.TomcatA.host=192.168.100.179
根据其工作机制的不同,worker有多种不同的类型,这是需要为每个worker定义的一项属性woker.<work name>.type。常见的类型如下:
◇ ajp13:此类型表示当前worker为一个运行着的Tomcat实例。
◇ lb:lb即load balancing,专用于负载均衡场景中的woker;此worker并不真正负责处理用户请求,而是将用户请求调度给其它类型为ajp13的worker。
◇ status:用户显示分布式环境中各实际worker工作状态的特殊worker,它不处理任何请求,也不关联到任何实际工作的worker实例。具体示例如请参见后文中的配置。
worker其它常见的属性说明:
◇ host:Tomcat 7的worker实例所在的主机;
◇ port:Tomcat 7实例上AJP1.3连接器的端口;
◇ connection_pool_minsize:最少要保存在连接池中的连接的个数;默认为pool_size/2;
◇ connection_pool_timeout:连接池中连接的超时时长;
◇ mount:由当前worker提供的context路径,如果有多个则使用空格格开;此属性可以由JkMount指令替代;
◇ retries:错误发生时的重试次数;
◇ socket_timeout:mod_jk等待worker响应的时长,默认为0,即无限等待;
◇ socket_keepalive:是否启用keep alive的功能,1表示启用,0表示禁用;
◇ lbfactor:worker的权重,可以在负载均衡的应用场景中为worker定义此属性;
三、httpd基于jk_module模块实现tomcat Cluster负载均衡
1、部署node6上的tomcatA
过程和上面的一样这里就不贴出来了,只是修改下测试页面
[root@BAIYU_179 ~]# cd /usr/local/tomcat/ [root@BAIYU_179 tomcat]# ls bin lib logs RELEASE-NOTES temp work conf LICENSE NOTICE RUNNING.txt webapps [root@BAIYU_179 tomcat]# cd webapps/ [root@BAIYU_179 webapps]# ls docs examples host-manager index.jsp manager ROOT testapp [root@BAIYU_179 webapps]# cd testapp/ [root@BAIYU_179 testapp]# ls classes index.jsp index.jsp.orig lib META-INF WEB-INF [root@BAIYU_179 testapp]# vi index.jsp <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="red">TomcatA </h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("abc","abc"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
测试:
2、修改node5上jk_module模块的配置信息
[root@BAIYU_175 conf.d]# ls d_jd.conf README workers.properties mod_jd.conf.orig welcome.conf workers.properties.orig [root@BAIYU_175 conf.d]# vi mod_jd.conf 1 LoadModule jk_module modules/mod_jk.so 2 JkWorkersFile /etc/httpd/conf.d/workers.properties 3 JkLogFile logs/mod_jk.log 4 JkLogLevel info 5 JkMount /status ! 6 JkMount /* tcsrvs #只是修改了这行,把代理至后端单个tomcat改成后端一组tomcat 7 JkMount /status StatA [root@BAIYU_175 conf.d]# vi workers.properties 1 worker.list=tcsrvs,StatA 2 worker.TomcatB.host=192.168.200.180 3 worker.TomcatB.port=8009 4 worker.TomcatB.type=ajp13 5 worker.TomcatB.lbfactor=1 #权重,调度因子 6 worker.TomcatA.host=192.168.200.179 7 worker.TomcatA.port=8009 8 worker.TomcatA.type=ajp13 9 worker.TomcatA.lbfactor=1 10 worker.StatA.type=status 11 worker.tcsrvs.type=lb # 12 worker.tcsrvs.balance_workers=TomcatA,TomcatB [root@BAIYU_175 conf.d]# service httpd configtest httpd: apr_sockaddr_info_get() failed for BAIYU_175 httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName Syntax OK [root@BAIYU_175 conf.d]# service httpd reload 重新载入 httpd:
测试:
发现已经实现了轮询调度后面的TomcatA,TomcatB,如果不能轮询调度,可以启用了sticky_session,再在workers.properties配置文件中添加workstick.tcsrvs.sticky_session=0,不启用sticky_session.
在负载均衡模式中,专用的属性还有:
◇balance_workers:用于负载均衡模式中的各worker的名称列表,需要注意的是,出现在此处的worker名称一定不能在任何worker.list属性列表中定义过,并且worker.list属性中定义的worker名字必须包含负载均衡worker。具体示例请参见后文中的定义。
◇ method:可以设定为R、T或B;默认为R,即根据请求的个数进行调度;T表示根据已经发送给worker的实际流量大小进行调度;B表示根据实际负载情况进行调度。
◇sticky_session:在将某请求调度至某worker后,源于此址的所有后续请求都将直接调度至此worker,实现将用户session与某worker绑定。默认为值为1,即启用此功能。如果后端的各worker之间支持session复制,则可以将此属性值设为0。
3、jk_module的状态页面
在此页面可以查看到后端主机的状态,并修改他们的配置信息,
注意:生产环境中此页面不应该让人随意访问,做个访问控制咯
四、httpd基于proxy_module模块实现tomcat Cluster负载均衡
1、修改http的配置文件
[root@BAIYU_175 conf.d]# ls d_jd.conf README workers.properties mod_jd.conf.orig welcome.conf workers.properties.orig [root@BAIYU_175 conf.d]# mv mod_jd.conf mod_jd.conf.bak [root@BAIYU_175 conf.d]# vi http-tomcat.conf 1 <Proxy balancer://tcsrvs> 2 BalancerMember http://192.168.200.179:8080 loadfactor=1 #把协议改成ajp,和对应的端口8009也可 3 BalancerMember http://192.168.200.180:8080 loadfactor=1 4 </Proxy> 5 NameVirtuaLHost *:80 6 <VirtuaLHost *:80> 7 ServerName www.a.com 8 ProxyVia on 9 ProxyRequests off 10 ProxypreserveHost ON 11 <Proxy *> 12 Order deny,allow 13 allow from all 14 </Proxy> 15 16 ProxyPass / balancer://tcsrvs/ 17 ProxyPassReverse / balancer://tcsrvs/ 18 <Location /> 19 Order deny,allow 20 allow from all 21 </Location> 22 </virtuaLHOST> [root@BAIYU_175 conf.d]# service httpd configtest httpd: apr_sockaddr_info_get() failed for BAIYU_175 httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName Syntax OK [root@BAIYU_175 conf.d]# service httpd reload 重新载入 httpd:
测试:也是成功的,这里就不上图了,,
如果Proxy指定是以balancer://开头,即用于负载均衡集群时,其还可以接受一些特殊的参数,如下所示:
◇lbmethod:apache实现负载均衡的调度方法,默认是byrequests,即基于权重将统计请求个数进行调度,bytraffic则执行基于权重的流量计数调度,bybusyness通过考量每个后端服务器的当前负载进行调度。
◇ maxattempts:放弃请求之前实现故障转移的次数,默认为1,其最大值不应该大于总的节点数。
◇ nofailover:取值为On或Off,设置为On时表示后端服务器故障时,用户的session将损坏;因此,在后端服务器不支持session复制时可将其设置为On。
◇ stickysession:调度器的sticky session的名字,根据web程序语言的不同,其值为JSESSIONID或PHPSESSIONID。
上述指令除了能在banlancer://或ProxyPass中设定之外,也可使用ProxySet指令直接进行设置,
如:
<Proxy balancer://hotcluster>
BalancerMember http://www1.magedu.com:8080 loadfactor=1
BalancerMember http://www2.magedu.com:8080 loadfactor=2
ProxySet lbmethod=bytraffic
</Proxy>
ProxyPassReverse:用于让apache调整HTTP重定向响应报文中的Location、Content-Location及URI标签所对应的URL,在反向代理环境中必须使用此指令避免重定向报文绕过proxy服务器。
2、proxy_module模块的状态页面
[root@BAIYU_175 conf.d]# vi http-tomcat.conf 1 <Proxy balancer://tcsrvs> 2 BalancerMember http://192.168.200.179:8080 loadfactor=1 3 BalancerMember http://192.168.200.180:8080 loadfactor=1 4 </Proxy> 5 NameVirtuaLHost *:80 6 <VirtuaLHost *:80> 7 ServerName www.a.com 8 ProxyVia on 9 ProxyRequests off 10 ProxypreserveHost ON 11 <Proxy *> 12 Order deny,allow 13 allow from all 14 </Proxy> 15 ProxyPass /balancer-manager ! 16 ProxyPass / balancer://tcsrvs/ 17 ProxyPassReverse / balancer://tcsrvs/ 18 <Location /> 19 Order deny,allow 20 allow from all 21 </Location> 22 #用于mod_proxy状态信息的输出 23 <Location /balancer-manager> 24 SetHandler balancer-manager 25 Proxypass ! 26 Order Deny,Allow 27 Allow from all 28 </Location> 29 </virtuaLHOST>
五、Tomcat的会话管理器
1、Manager组件
Manger对象用于实现HTTP会话管理的功能,Tomcat中有5种Manger的实现:
(1).StandardManager
Tomcat的默认会话管理器,用于非集群环境中对单个处于运行状态的Tomcat实例会话进行管理。当Tomcat关闭时,这些会话相关的数据会被写入磁盘上的一个名叫SESSION.ser的文件,并在Tomcat下次启动时读取此文件。
<Manager className="org.apache.catalina.session.StandardManager"
maxInactiveInterval="7200"/>
默认保存于$CATALINA_HOME/work/Catalina/<hostname>/<webapp-name>/下的SESSIONS.ser文件中。
maxActiveSessions:最多允许的活动会话数量,默认为-1,表示不限制;
maxInactiveInterval:非活动的会话超时时长,默认为60s;
pathname:会话文件的保存目录;
服务器重启会话信息可能会丢失,
(2).PersistentManager
当一个会话长时间处于空闲状态时会被写入到swap会话对象,这对于内存资源比较吃紧的应用环境来说比较有用。
将会话数据保存至持久存储中,并且能在服务器意外中止后重新启动时重新加载这些会话信息。持久会话管理器支持将会话保存至文件存储(FileStore)或JDBC存储(JDBCStore)中。
保存至文件中的示例:
<Manager className="org.apache.catalina.session.PersistentManager"
saveOnRestart="true">
<Store className="org.apache.catalina.session.FileStore"
directory="/data/tomcat-sessions"/>
</Manager>
每个用户的会话会被保存至directory指定的目录中的文件中,文件名为<session id>.session,并通过后台线程每隔一段时间(checkInterval参数定义,默认为60秒)检查一次超时会话。
保存至JDBCStore中的示例:
<Manager className="org.apache.catalina.session.PersistentManager"
saveOnRestart="true">
<Store className="org.apache.catalina.session.JDBCStore"
driverName="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mydb?user=jb;password=pw"/>
</Manager>
(3).DeltaManager (session多播复制)
用于Tomcat集群的会话管理器,它通过将改变了会话数据同步给集群中的其它节点实现会话复制。这种实现会将所有会话的改变同步给集群中的每一个节点,也是在集群环境中用得最多的一种实现方式。
(4).BackupManager(两两备份,拓扑困难)
用于Tomcat集群的会话管理器,与DeltaManager不同的是,某节点会话的改变只会同步给集群中的另一个而非所有节点。
1,2我感觉有错误吧,混了,但这里不管了,一般只用到DeltaManager,这种方式网络资源消耗过大,也只适合3-5个节点的集群,
2、基于DeltaManager实现seession复制
1)修改tomcat的配置文件server.xml
<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.103.40.41" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.200.180" 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.TcpFailureDetect or"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch1 5Interceptor"/> </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.ClusterSessionListener"/> </Cluster>
以上内容定义在Engine容器中,则表示对所有主机均启动用集群功能。如果定义在某Host中,则表示仅对此主机启用集群功能。(注,tomcatA与tomcatB都要修改!)
2)在web.xml文件中添加<distributable\>
此外,所有启用集群功能的web应用程序,其web.xml中都须添加<distributable/>才能实现集群功能。如果某web应用程序没有自己的web.xml,也可以通过复制默认的web.xml至其WEB-INF目录中实现。
[root@BAIYU_179 conf]# ls Catalina context.xml server.xml.bak tomcat-users.xml.orig catalina.policy logging.properties server.xml.orig tomcat-users.xsd catalina.properties server.xml tomcat-users.xml web.xml [root@BAIYU_179 conf]# cd .. [root@BAIYU_179 tomcat]# ls bin conf lib LICENSE logs NOTICE RELEASE-NOTES RUNNING.txt temp webapps work [root@BAIYU_179 tomcat]# cd webapps/ [root@BAIYU_179 webapps]# ls docs examples host-manager manager ROOT testapp [root@BAIYU_179 webapps]# cd testapp/ [root@BAIYU_179 testapp]# ls classes index.jsp index.jsp.orig lib META-INF WEB-INF [root@BAIYU_179 testapp]# cp /usr/local/tomcat/conf/web.xml . [root@BAIYU_179 testapp]# vi web.xml <distributable /> #添加该行
测试:
可以从图中看到,不管你怎么刷新Session ID都不会变,说明我们的Tomcat的DeltaManager集群配置完成,实现了多台主机之间会话共享。
总结:构建DeltaManager集群步骤:
1、在各节点的server.xml的engine或host容器添加如上内容;
注意修改MemberShip组件中的多播地址address="228.0.0.4",建议修改Receiver中的address为本机能够传递心跳信息的地址;
2、在各节点为使用组播地址添加组播路由,格式:
route add -net $MCAST_ADDRESS netmask 255.255.255.255 dev eth0
3、在相应应用程序的web.xml中添加<distributable/>;