4

nginx实现session共享

 3 years ago
source link: https://blog.csdn.net/lolly1023/article/details/112612289
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在nginx实现了负载均衡之后,用户第一次请求的tomcat和第二次请求的tomcat基本不是同一个,但是你在第一次请求放在session中的值只有一个tomcat1才有,第二个请求的那个tomcat2里面是没有的。这样就出现了用户不停登入的情况。为了解决这个session共享的问题,于是我们提出了以下几个方案:

nginx实现session共享

ip_hash(ip绑定)

原理:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

直接在配置文件里面添加ip_hash 则可以实现ip绑定,ip绑定 和什么浏览器没有关系,是和本机电脑ip有关系,A B 两个客户端,如果 nginx配置ip绑定以后 A 客户端如果请求的 是8080 服务器,则以后来自客户端的A 的请求都将交给8080服务器处理,如果是IP 绑定,在高并发的情况下,也没有什么作用,但是 ip绑定可以实现 会话共享

upstream backserver {
ip_hash;
	server 192.168.0.14:88;
	server 192.168.0.15:80;
}

优点:实现也比较简单,需要修改一下nginx的配置文件即可
缺点

  • 一大堆人连同一个网访问的时候,就没有负载均衡这一说了,这一大堆的ip都是一样,都去访问同一个tomcat。
  • 如果这个人访问的tomcat突然挂了,那nginx的故障转移机制将会分发给另一个tomcat服务器,这样一来所有请求这个tomcat的所有用户就又需要重新登入了。
  • 如果这个人用着用着突然在用的网络不稳定,然后这个人换了另一个网,这样ip一换,这个人又要重新登入了。
    小结:这样的解决方案能简单的实现,但是不能满足商业需求。

tomcat集群实现session的共享

原理:这个方法原理比较简单,就是有几个tomcat,就复制了几个session,比如一个tomcat的session发生了改变,其余tomcat的session也会复制发生改变,保证了用户的session在所有的tomcat中都是相同的。

创建一个web项目

在起始页index.jsp中写入以下代码(便于之后观察)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>  
  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <base href="<%=basePath%>">  
      	
    <title>My JSP 'index.jsp' starting page</title>  
    <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">      
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
    <meta http-equiv="description" content="This is my page">  
    <!-- 
    <link rel="stylesheet" type="text/css" href="styles.css"> 
    -->  
  </head>  
    
  <body>  
      
        SessionID:<%=session.getId()%>  
        <BR>  
        SessionIP:<%=request.getServerName()%>  
        <BR>  
        SessionPort:<%=request.getServerPort()%>  
        <%  
        out.println("This is Tomcat Server 111");  
        %>  
  </body>  
</html>  

记得修改一下输出语句,进行不同tomcat的区分
写入之后,在web.xml中添加一个<distributable/>节点,放在display下面
在这里插入图片描述

复制一份tomcat到文件夹中

(文件夹用于储存tomcat)
在这里插入图片描述
两个tomcat内容都是一样的,只不过文件夹命名不一样

导出war包

放到tomcat的的webapps中

导出两次,第二次的时候,把输出语句换成2222,以便于观察,把第二次导出的war包放入到tomcat2中,第一次的就是放在tomcat1中。
在这里插入图片描述

修改server.xml

打开tomcat的conf文件夹,对server.xml文件修改
找到<Engine name="Catalina" defaultHost="localhost">这一条语句,在此语句后输入:

<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"/>  
  
         <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>

修改端口及工作路径

修改端口
打开tomcat的conf文件夹,对server.xml文件修改,修改成不一样的即可,我为了简便,修改为如下:

tomcat1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
tomcat2
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
修改工作路径
打开tomcat的bin文件夹,对startup.bat文件修改
@echo off前面加上:

set TLTLE="tomcat002"
set CATALINA_BASE="D:\tomcat_cluster\tomcat002"
set CATALINA_HOME="D:\tomcat_cluster\tomcat002"

记得两个tomcat都要修改

启动tomcat

两个都要启动(忽略乱码问题)
在这里插入图片描述

修改nginx配置文件

修改conf路径下的nginx.conf文件
在这里插入图片描述

  • 第一个参数为为自己的tomcat地址
  • weight:权重
  • fail_timeout:失败时间
  • max_fails:失败次数

fail_timeout与max_fails可以理解为,在fail_timeout的时间内,失败max_fails次,那就把请求分配给其他服务器

测试是否成功

在浏览器输入自己的url以及端口测试
在这里插入图片描述
测试成功:是两个不同的tomcat,但是是一样的session,session共享成功

关闭nginx

在这里插入图片描述
再次进入已经显示进不去了,证明nginx关闭了
在这里插入图片描述

优点:实现简单,没有什么花里胡哨的操作。如果集群中的tomcat的个数不多,而且用户没有那么多的时候可以选择这种方式。
缺点:只要Session数据有变化,就需要将数据同步到所有其他机器上,机器越多,同步带来的网络带宽开销就越大;当用户很多时,每台机器用于保存Session数据的内容占用会很严重。


redis实现session的共享

暂未学习,学习之后再加入。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK