nginx实现session共享

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

文章目录

  • nginx实现session共享
    • ip_hash(ip绑定)
      • 步骤实现
        • 大致描述
        • 优缺点
    • tomcat集群实现session的共享
      • 步骤实现
        • 创建一个web项目
        • 复制一份tomcat到文件夹中
        • 导出war包
        • 修改server.xml
        • 修改端口及工作路径
        • 启动tomcat
        • 修改nginx配置文件
        • 测试是否成功
        • 关闭nginx
        • 优缺点
    • redis实现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+"/";  
%>  
  
  
<html>  
  <head>  
    <base href="<%=basePath%>">  
      	
    <title>My JSP 'index.jsp' starting pagetitle>  
    <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">  
      
  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中添加一个节点,放在display下面
nginx实现session共享_第1张图片

复制一份tomcat到文件夹中

(文件夹用于储存tomcat)
nginx实现session共享_第2张图片
两个tomcat内容都是一样的,只不过文件夹命名不一样

导出war包

放到tomcat的的webapps中

导出两次,第二次的时候,把输出语句换成2222,以便于观察,把第二次导出的war包放入到tomcat2中,第一次的就是放在tomcat1中。
nginx实现session共享_第3张图片

修改server.xml

打开tomcat的conf文件夹,对server.xml文件修改
找到这一条语句,在此语句后输入:

<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实现session共享_第4张图片

修改nginx配置文件

修改conf路径下的nginx.conf文件
nginx实现session共享_第5张图片

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

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

测试是否成功

在浏览器输入自己的url以及端口测试
nginx实现session共享_第6张图片
测试成功:是两个不同的tomcat,但是是一样的session,session共享成功

关闭nginx

nginx实现session共享_第7张图片
再次进入已经显示进不去了,证明nginx关闭了
nginx实现session共享_第8张图片

优缺点

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


redis实现session的共享

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

你可能感兴趣的:(nginx,nginx,tomcat,负载均衡)