前端使用httpd作为反代负载均衡至后端tomcat主机:tomcat可用memcached当做会话服务器保存会话:
实验环境:物理机win7,虚拟机centos7
node1:172.18.11.111 TomcatA
node2:172.18.11.112 TomcatB
node3:172.18.11.113 调度器httpd
安装tomcat
分别在node1和node2安装tomcat:
]# yum -y install java-1.7.0-openjdk java-1.7.0-openjdk-devel
]# vim /etc/profile.d/java.sh
export JAVA_HOME=/usr
]# . /etc/profile.d/java.sh
]# yum -y install tomcat tomcat-lib tomcat-webapps tomcat-admin-webapps
]# cd /var/lib/tomcat/webapps/
]# mkdir testapp
]# cd testapp/
]# mkdir classes lib WEB-INF META-INF
]# vim index.jsp
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
<head>
<title>JSP Test Page </title>
</head>
<body>
<% out.println("hello world,tomcat 1,172.18.11.111") ;
%>
</body>
</html>
]# scp -r /var/lib/tomcat/webapps/testapp/ node2:/var/lib/tomcat/webapps/
修改node2上配置:
]# vim /var/lib/tomcat/webapps/testapp/index.jsp
仅修改一条:<% out.println("hello world,tomcat 2,172.18.11.112") ;
在node3:
编译安装jk模块,此模块不是httpd默认的模块需要编译才能使用;
安装开发环境:
]# yum groupinstall "Development Tools" "Server Platform Development"
需要安装httpd自己的开发包,才能编译安装第三方模块;
]# yum -y install httpd-devel
]# which apxs
/usr/bin/apxs
编译时会用到此路径;
下载jk模块并解压:
]# tar xf tomcat-connectors-1.2.40-src.tar.gz
]# cd tomcat-connectors-1.2.40-src/native/
]# ./configure --with-apxs=/usr/bin/apxs
]# make
]# make install
显示部分内容:
chmod 755 /usr/lib64/httpd/modules/mod_jk.so
表示编译完成;
]# vim /etc/httpd/conf.d/mod_jk.conf
]# vim /etc/httpd/conf.d/workers.properties
]# httpd -t
显示:Syntax OK
]# systemctl reload httpd.service
浏览器输入:http://172.18.11.113/test/
刷新实现负载均衡效果;负载均衡效果,node1和node2比例为1:2;
如有要实现会话绑定,只需在/etc/httpd/conf.d/workers.properties配置文件中添加:
worker.tcsrvs.sticky_session=1
但还需要在node1和node2上,在tomcat配置文件/etc/tomcat/server.xml中的Engine配置段添加一个‘jvmRoute=’指令,用来标识tomcat服务器的id号;
在node1上:
]# vim /etc/tomcat/server.xml
<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatA">
]# systemctl restart tomcat.service
在node2上:
]# vim /etc/tomcat/server.xml
<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatB">
]# systemctl restart tomcat.service
浏览器输入:http://192.168.255.3/test/
实现会话绑定。
以上仅实现了使用httpd的jk模块及做会话绑定的演示。但基于会话粘性绑定会话实际并不使用,因为此种方法会损害负载均衡的效果,而且一旦有一台服务器掉线,则该服务器上的会话将丢失。
而实际中可用会话服务器为tomcat保存会话,而使用memcached就可做会话服务器。配置如下:
根据以上配置负载均衡的基础上,基于memcached做tomcat的会话服务器:
使用会话服务器,必须要tomcat支持,而tomcat默认不支持,需要借助第三方程序;
会话在内存中保存时它们是一个对象,tomcat是面向对象的,所以内部所有都是对象;对象都有特定结构,而网络传输都是要序列化数据后才能传输的;会话服务器只能存储序列化数据,默认对象都不是序列化的;
需要序列化工具将会话对象先转换成序列格式,才能存储在会话服务器上(memcached中);让tomcat的会话保存在memcached中,memcached当做一个会话服务器;
不同的会话服务器存储数据时虽然相同,但不同的序列化工具在将数据序列化时有可能是不同的;所以对象序列化工具也有多种,例如memcached-session-manager;跟tomcat版本密切相关,根据使用的tomcat版本来下载相对应的memcached-session-manager版本。
下载memcached-session-manager所需要到相关的类库:
javolution-5.5.1.jar
memcached-session-manager-1.8.2.jar
memcached-session-manager-tc7-1.8.2.jar
msm-javolution-serializer-1.8.2.jar
spymemcached-2.10.2.jar
把这些类库拷贝到tomcat安装时的类库目录下:
]# cp * /usr/share/tomcat/lib/
拷贝一份给node2:
]# scp -r msm/* node2:/usr/share/tomcat/lib/
停止node1和node2的tomcat
]# systemctl stop tomcat.service
实验时,就把node1和node2即当两台tomcat主机又当两台memcached会话服务器:
安装memcached:
在node1和node2:
]# yum -y install memcached
]# systemctl start memcached.service
]# ss -tnl 确保11211端口监听;
使用memcached会话服务器,对tomcat而言则是引入了新的会话管理器;
可把这个会话管理器放在Engine、Context、Host中均可,根据想要在哪个级别生效就放在哪个配置段里;
在node1:
]# vim /etc/tomcat/server.xml
...
<Context path="/test" docBase="testapp">
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:172.18.11.111:11211,n2:172.18.11.112:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
/>
</Context>
...
复制一份该配置文件给node2:
]# scp /etc/tomcat/server.xml node2:/etc/tomcat/
在node2:
]# vim /etc/tomcat/server.xml
只改:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatB">
分别在node1和node2启动tomcat:
]# systemctl start tomcat
浏览器输入:http://172.18.11.113/test/test.jsp
刷新后,调度到后端不同主机响应,但会话始终没有变;
手动使n2的memcached会话服务器掉线:
测试另一台会话服务器仍能工作:
注意:此会话信息中因为含有后端服务器的信息,所以在会话服务器切换时会话会改变;这可能因为jsp程序的问题,如果会话信息中不添加后端主机的信息,当调度到不同主机响应时,会话信息应该是不会变化的。