会话是指一个终端用户与交互系统进行通讯的过程,比如从输入账户密码进入操作系统到退出操作系统就是一个会话过程。会话较多用于网络上,TCP的三次握手就创建了一个会话,TCP关闭连接就是关闭会话。
Http协议是一种无状态协议,所以需要使用Session机制来保存用户的状态,比如登录状态、常用信息等。
Session用于保存一次会话的相关信息,可以实现在多个页面之间共享这些数据。
例如:你打开淘宝登录了个人账号,即使你浏览了再多的店铺宝贝,切换了很多的页面,用户名是不变的,这个就是Session起的作用。直到你关闭浏览器,Session被销毁,才会清除掉之前的登录记录。
今天和大家分享“Nginx+tomcat实现负载均衡的会话保持”就是实现:如果网站某个负载节点挂掉,请求被分配到新节点Session也会同步过来,实现会话保持,由此保证用户无感知的浏览。
测试环境单台服务器开了两个tomcat,一台对应8080端口,另一台对应8090端口。
复制以下内容到 Engine下
添加此模块:
<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="192.168.224.145" port="4001" 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>
备注:
1.classname配置tomcat集群在进行信息传递时互相使用什么类来进行传递
2.manager决定如何管理集群的session信息
3.Channel是Tomcat节点之间进行通讯的工具。
4.Membership维护集群的可用节点列表。用于检测新增节点及掉线节点
5.Receiver : 接收器
如果port为4000,autoBind为100,接收器将在4000-4099间取一个端口,进行监听
6.sender:发送器负责发送消息
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel>
7.Valve :过滤器
8.Deployer:同步集群下的所有节点的一致性
9.ClusterListener : 监听器,监听Cluster组件接收的消息,使用DeltaManager时,Cluster接收的信息通过ClusterSessionListener传递给DeltaManager
在web.xml中添加属性,用于告诉web容器,该项目属于分布式项目
添加标签到web项目WEB-INF目录
webapps/ROOT/index.jsp 创建测试页面获取sessionID
tomcatA <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="red">TomcatA</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("TomcatA","TomcatA"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html> tomcatB <%@ page language="java" %> <html> <head><title>TomcatB</title></head> <body> <h1><font color="red">TomcatB</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("TomcatB","TomcatB"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
tomcat实现会话保持有多种实现方式,这里只介绍了Manager对象实现,优点是利用tomcat自身集群session复制实现会话保持配置方便,缺点是像阿里云ECS这种不支持组播就无法用这种方式实现了。也可以使用memcache或redis存储session会话,但这个要下载tomcat版本相对应的memcache jar包。