一、为什么要实现会话保持 因为http协议是一种无状态的协议,客户端和服务器建立连接在完成数据传输之后即断开连接,当客户端再次请求建立连接的时候,服务器并不知道两次连接之间有什么联系,只会当做一次新的连接请求。 二、会话保持的实现方法 1、IP地址绑定 可以通过某种算法,建立客户端的IP地址与后端服务器之间的映射关系,使同一个客户端通过负载均衡器调度到的是同一个后端服务器,这样用户的session总是有效的。例如nginx的实现反向代理的ip_hash算法,LVS的sh调度算法以及haproxy的source算法等,都可以实现这个功能。 缺点:这种调度在一定程度上影响了负载均衡的效果,而且如果调度到的后端服务器如果宕机,session就丢失了。 2、session粘性 同一个session请求备调度到同一台服务器,粒度小,以session为调度单位。 2.1session服务器 为了提高性能,可以使用单独的服务器用来存储session,所有提供服务的服务器都使用该session服务器上共享的session,这样任何一台后端服务器宕机都不会影响到客户端的访问。 2.2session复制集群 使用Tomcat的session cluster,通过session复制机制,实现session的同步,使得每台服务器上都拥有全部的用户会话,无论前端负载均衡器如何调度,后端每一台服务器都可以实现session的会话保持。 缺点:所有的机器上都保存所有和会话信息,对于访问量比较大的粘连,session对内存的消耗是非常大的 三、实验 Tomcat+nginx实现会话保持
配置nginx实现负载均衡
upstream tomcat_cluster{
server 172.17.253.59:8080 weight=1;
server 172.17.252.63:8080 weight=2;
}
server {
listen 80 default_server;
server_name _;
root /usr/local/tomcat/webapps/ROOT;
index index.jsp
include /etc/nginx/default.d/*.conf;
location ~* \.(jsp|do)$ {
proxy_pass http://tomcat_cluster;
}
}
配置Tomcat
vim /usr/local/tomcat/conf/server.xml
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<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" frequency="500" dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto" 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"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
创建一个测试页面
[root@web-server2-70 test]# ls
index.jsp session.jsp WEB-INF
[root@web-server2-70 test]# pwd
/usr/local/tomcat/webapps/test
[root@web-server2-70 test]# vim session.jsp
<%@ page language="java" %>
<html>
<head><title>TomcatA</title></head>
<body>
<font color="blue">TomcatA
<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>
在测试页面饿站点目录下创建WEB-INF目录,在目录下创建web.xml并且在最后添加以下内容:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<distributable/>
</web-app>
测试