zoukankan      html  css  js  c++  java
  • 集群环境下session共享解决方案

    概述

      在搭建完集群环境后,不得不考虑的一个问题就是用户访问产生的session如何处理。比如集群中存在A,B两台服务器,用户在第一次访问网站时,nginx通过其负载均衡机制将用户请求转发到A服务器中,这是A服务器就是给用户创建一个Session。当用户第二次发送请求时,nginx将其负载均衡到B服务器中,而这时B服务器并不存在session,所以这样就会出现问题。这将导致数据的流失,大大降低了用户的体验度。

    解决方案:

      1.nginx或者haproxy做的负载均衡,用nginx做的负载均衡可以添加ip_hash这个配置;用haproxy做的负载均衡可以用balance source这个配置,从而使用一个IP的请求发到同一个服务器;

      2.利用数据库同步session;

      3.利用cookie同步session数据,但是安全性差,http请求都需要带参增加了带宽消耗;

      4.Tomcat配置session共享;

      5利用session集群存放Redis;

    使用nginx做的负载均衡添加一个ip_hash配置

      步骤一:创建一个工程,启动两个Tomcat

        

      步骤二:编写一个servlet测试  

    @WebServlet("/nginxSessionServlet")
    public class NginxSessionServlet  extends HttpServlet {
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           doGet(req,resp);
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("当前使用端口:"+req.getLocalPort());
            String action = req.getParameter("action");
            if (action.equals("setSession")){
                req.getSession().setAttribute("username","wnwn");
                resp.getWriter().write("success");
            }else if (action.equals("getSession")){
                resp.getWriter().write((String)req.getSession().getAttribute("username"));
            }
        }
    }

       步骤三:在没有使用nginx访问的效果如下:

        现在启动的端口有8080和8081

        1.使用http://localhost:8080/nginxSessionServlet?action=setSession地址访问(端口为8080,但是是setSession存入数据)

          

        2.使用http://localhost:8080/nginxSessionServlet?action=getSession地址访问(端口为8080,但是是getSession取出数据)

     

           

        3.使用http://localhost:8081/nginxSessionServlet?action=getSession地址访问(端口为8081, 方法是getSession取出数据)

          在8081端口中使用getSession取出8080中set的数据时不可以的,所以下面我们要解决session共享问题

          

       步骤四:配置nginx.conf文件

      upstream myserver{
             ip_hash;
             server 127.0.0.1:8080;
             server 127.0.0.1:8081;
        }
        server{
            listen       81;
            server_name  www.bproject.com;
            location / {
                root   html;
                proxy_pass  http://myserver;
                index  index.html index.htm;
            }
        }

      步骤五:启动nginx,并访问

        1.使用http://www.bproject.com:81/nginxSessionServlet?action=setSession地址访问

          

         控制台输出结果

          

        2.使用http://www.bproject.com:81/nginxSessionServlet?action=getSession地址访问

          

           控制台访问结果

          

        3.使用http://www.bproject.com:81/nginxSessionServlet?action=getSession地址再次访问页面

          

        4.结论: 当第一次请求时,负载均衡将请求转发到8080端口上,因为配置了ip_hash,所以每次请求都会转发到8080端口上,相当于把请求和8080端口粘到一块了。

    利用spring-session+Redis

       步骤一:创建一个springboot工程,启动两次,端口分别为8082和8083

        

      步骤二:导入依赖

            <!--spring boot 与redis应用基本环境配置 -->
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-redis</artifactId>
            </dependency>
    
            <!--spring session 与redis应用基本环境配置,需要开启redis后才可以使用,不然启动Spring boot会报错 -->
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-data-redis</artifactId>
            </dependency>

      步骤三:创建controller测试

    @RestController
    public class SessionController {
    
        @RequestMapping("/setSession")
        public String setSession(HttpServletResponse response, HttpServletRequest request) throws IOException {
            request.getSession().setAttribute("username","wang");
            return "success";
        }
    
        @RequestMapping("/getSession")
        public String getSession(HttpServletRequest request,HttpServletResponse response){
            String username = (String) request.getSession().getAttribute("username");
            return username;
        }
    }

      步骤四:application.properties文件

    server.port=8082
    #server.port=8083
    #redis配置 spring.redis.password: wang2003

      步骤五:启动项目测试

       1.使用http://localhost:8082/setSession地址访问(端口为8082)

          

          页面返回success时,就成功将数据添加到Redis缓存中了

          

        2.使用http://localhost:8082/getSession地址访问数据(端口为8082)

          

        3.使用http://localhost:8083/getSession地址访问数据(端口为8083)

          

        4.结论:该方案配置简单,数据安全且稳定,效率高,被普遍使用;

           注意:在Redis中删除这个数据包,8082和8083端口都get不到session了,说明了session没有存在在JVM中,而是转存在Redis中;

  • 相关阅读:
    java Des 加密解密技术
    JAVA处理外部链接的方法
    javascript 中escape、encodeURI、encodeURIComponent 区别
    JQuery与JS 遍历和操作 父页面控件的比较
    JS 添加删除元素 /DOM
    jquery 验证所有text,textare非法字符
    jquery url检测遇到的jquery跨域问题及JSONP的使用
    二叉树遍历非递归算法——后序遍历
    二叉树遍历非递归算法——中序遍历
    二叉树遍历非递归算法——先序遍历
  • 原文地址:https://www.cnblogs.com/wnwn/p/12298515.html
Copyright © 2011-2022 走看看