概述:企业应用中nginx+tomcat是当前主流架构之一,当网站访问量很大的时候一台nginx代理多台tomcat来实现负载均衡是一个比较理想的解决方案,那如何保持会话呢?(也就是当一个链接访问A服务器时,刷新浏览器链接跳转到B服务器,而不会使页面失效呢?)

解决方案:

	1、会话粘性(session sticky),又分为基于源ip和cookie 2种方式
				基于源ip(source_ip)在不同的调度器上又不同的实现方式:
									nginx : ip_hash
									lvs : sh算法
									haproxy:source
				
				cookie:
									nginx : hash
									haproxy:cookie
	2、会话群集(session cluster)tomcat自带的session manager
	3、会话服务 (session server) 第三方redis(store),memcached(cache)

环境: nginx+tomcat 一台nginx :192.168.2.198 一台tomcat1+mem:192.168.2.197 一台tomcat2+mem:192.168.2.199

一、2台Tomcat配置java环境及发布目录 1、jdk安装 rpm -ivh jdk-8u151-linux-x64.rpm
如图: 2、tomcat下载、解压 tomcat 下载地址:http://tomcat.apache.org/ tar xf apache-tomcat-7.0.78.tar.gz -C /usr/local/ ln -s apache-tomcat-7.0.78 tomcat 3、配置path环境变量 vi /etc/profile.d/tomcat.sh export CATALINA_BASE=/usr/local/tomcat export PATH=$CATALINA_BASE/bin:$PATH chmod +x /etc/profile.d/tomcat.sh # 赋予可执行权限 source /etc/profile.d/tomcat.sh 4、创建测试网页的发布目录 mkdir /usr/local/tomcat/webapps/test/ 5、创建测试页面(197上创建tomcatA ,199上创建tomcatB) [root@localhost conf]#vi /usr/local/tomcat_a/webapps/test/index.jsp <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <font color="red">TomcatA.linuxinfo.top</font> <tablealign="centre" border="1"> <tr> <td>SessionID</td> <% session.setAttribute("linuxinfo.top","linuxinfo.top");%> <td><%=session.getId() %></td> </tr> <tr> <td>Createdon</td> <td><%=session.getCreationTime() %></td> </tr> </table> </body> </html> 6、分别启动tomcat catalina.sh start #可也用全路径/usr/local/tomcat/bin/startup.sh 7、访问192.168.2.197,测试如下,查看session ID 访问192.168.2.199,测试如下,查看session ID

至此,2台tomcat部署成功。

二、基于tomcat群集配置session会话保持 1、编辑vi server.xml ,在Engine字段中添加如下代码,开启群集服务 <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> #jvmRoute表示唯一表示本机,所以不同主机的是不同的。这个参数非必须 <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.10.0.4" port="45564" frequency="500" dropTime="3000"/> #多播地址应该是224~239,同一组里的多播地址相同 <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.2.197" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> #address为本机能够向外通信的地址 <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"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>

如图: 2、编辑web.xml vim /usr/local/tomcat/conf/web.xml 给应用程序加<distributable/>标签,使其能够实现复制。在web-app字段加 <distributable/>。 如下图:

将web.xml放在对应的项目目录下: mkdir /usr/local/tomcat/webapps/test/WEB-INF cp /usr/local/tomcat/conf/web.xml /usr/local/tomcat/webapps/test/WEB-INF/ 重启服务:catalina.sh stop catalina.sh start 如果不能启动,查看日志logs/catalina.out信息如下(不能加入到组播) :blob.png 那么添加到达组播的路由即可:route add -host 228.10.0.4 dev ens33

三、配置nginx负载均衡 vi /usr/local/nginx/conf/nginx.conf upstream tomcat{ server 192.168.2.197:8080; server 192.168.2.199:8080; } server { listen 80; server_name localhost; location / { proxy_pass http://tomcat; } }

四、测试访问代理服务192.168.2.198,查看session ID 保持不变,实现会话保持。

强制刷新页面

可以看到session ID,保持不变,基于tomcat群集实现了会话保持。

五、基于memcache来实现session会话保持

0、还原配置文件 cp server.xml server.xml.cluster #备份群集复制的配置文件 cp server.xml.bak server.xml #还原配置文件

在所有的tomcat节点上(我们这里只有两台主机)既做tomcat也做memcached

下载五个jar包,将jar包放在/usr/local/tomcat/lib: 1、下载以下JAR包到tomcat库目录;cd /usr/share/tomcat/lib wget http://www.java2s.com/Code/JarDownload/javolution/javolution-5.5.1.jar.zip
#需要解压 unzip javolution-5.5.1.jar.zip wget http://repo1.maven.org/maven2/net/spy/spymemcached/1.8.0/spymemcached-1.8.0.jar wget http://repo1.maven.org/maven2/de/javakaffee/msm/msm-javolution-serializer/1.8.0/msm-javolution-serializer-1.8.0.jar wget http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager-tc7/1.8.0/memcached-session-manager-tc7-1.8.0.jar wget http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/2.1.1/memcached-session-manager-1.8.0.jar

mget javolution-5.4.3.1.jar
memcached-session-manager-1.8.0jar
memcached-session-manager-tc7-1.8.0.jar
msm-javolution-serializer-1.8.0.jar
spymemcached-1.8.0.jar

2、在contest.xml段定义一个用于测试的context容器,并在其中创建一个会话管理器。 vim contest.xml ,添加如下信息 <Context <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="m1:192.168.2.197:11211,m2:192.168.2.199:11211" failoverNodes="m1" requestUriIgnorePattern=".*.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"/> </Context> 重启服务: catalina.sh stop catalina.sh start 3、下载memcached,启动服务 yum install memcached -y systemctl start memcached 4、测试页面及测试效果同上