Spring-Session实现Session共享入门教程

任何一种技术的出现,都是来解决特定的问题的!

本篇开始学习Spring-Session相关的一些知识学习整理,让我们开始吧!

Spring-Session介绍

  1. Spring-Session使用的场景?

HttpSession是通过Servlet容器进行创建和管理的,在单机环境中。通过Http请求创建的Session信息是存储在Web服务器内存中,如Tomcat/Jetty。

假如当用户通过浏览器访问应用服务器,session信息中保存了用户的登录信息,并且session信息没有过期失,效那么用户就一直处于登录状态,可以做一些登录状态的业务操作!


Spring-Session实现Session共享入门教程_第1张图片
单机session

但是现在很多的服务器都采用分布式集群的方式进行部署,一个Web应用,可能部署在几台不同的服务器上,通过LVS或者Nginx等进行负载均衡(一般使用Nginx+Tomcat实现负载均衡)。此时来自同一用户的Http请求将有可能被分发到不同的web站点中去(如:第一次分配到A站点,第二次可能分配到B站点)。那么问题就来了,如何保证不同的web站点能够共享同一份session数据呢?

假如用户在发起第一次请求时候访问了A站点,并在A站点的session中保存了登录信息,当用户第二次发起请求,通过负载均衡请求分配到B站点了,那么此时B站点能否获取用户保存的登录的信息呢?答案是不能的,因为上面说明,Session是存储在对应Web服务器的内存的,不能进行共享,此时Spring-session就出现了,来帮我们解决这个session共享的问题!

Spring-Session实现Session共享入门教程_第2张图片
集群session
  1. 如何进行Session共享呢?

简单点说就是请求http请求经过Filter职责链,根据配置信息过滤器将创建session的权利由tomcat交给了Spring-session中的SessionRepository,通过Spring-session创建会话,并保存到对应的地方。

Spring-Session实现Session共享入门教程_第3张图片
session共享

实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat、Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis,Mongo)中,

而上面说的使用Nginx也可以,使用ip_hash策略。
【Nginx】实现负载均衡的几种方式
在使用Nginx的ip_hash策略时候,每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,也可以解决session的问题。

  1. Spring官方介绍
    Why Spring Session & HttpSession?

Spring会话提供了与HttpSession的透明集成,允许以应用程序容器(即Tomcat)中性的方式替换HttpSession,但是我们从中得到了什么好处呢?

  • 集群会话——Spring会话使支持集群会话变得微不足道,而不需要绑定到应用程序容器的特定解决方案。

  • 多个浏览器会话——Spring会话支持在单个浏览器实例中管理多个用户会话(也就是多个经过验证的帐户,类似于谷歌)。

  • RESTful api——Spring会话允许在header中提供会话id以使用RESTful api。

  • Spring Session & WebSockets的完美集成。

项目搭建

整个项目的整体骨架:

Spring-Session实现Session共享入门教程_第4张图片
项目的整体骨架

基于XML配置方式的Spring Session

本次只讲解xml配置方式,javaConfig配置可以参考官方文档:Spring Java Configuration

环境说明

本次项目需要用户Nginx和Redis,如果没有配置Nginx的请看这里: Windows上Nginx的安装教程详解

没有配置Redis的请看这里:Redis——windows环境安装Redis和Redis sentinel部署教程

配置好了上面的环境,后下面开始正式的Spring-session搭建过程了!

1.添加项目依赖

首先新建一个Maven的Web项目,新建好之后在pom文件中添加下面的依赖:



    4.0.0

    org.spring
    learn-spring-session
    1.0-SNAPSHOT
    war
    First Learn Spring Session

    
      1.7
      4.3.4.RELEASE
      1.3.1.RELEASE
    

    
        
        
            javax.servlet
            javax.servlet-api
            3.0.1
            provided
        

        
            org.springframework.session
            spring-session-data-redis
            ${spring-session.version}
            pom
        
        
       
            biz.paluch.redis
            lettuce
            3.5.0.Final
        
        
            org.springframework
            spring-web
            ${spring.version}
        


    

   




2.web.xml配置




  
    contextConfigLocation
    classpath*:spring/*xml
  

  
    org.springframework.web.context.ContextLoaderListener
  


  
  
    springSessionRepositoryFilter
    org.springframework.web.filter.DelegatingFilterProxy
  


  
    springSessionRepositoryFilter
    /*
    REQUEST
    ERROR
  


  
    index.jsp
  


        
        

3.Xml的配置

在resources 下面新建一个xml,名词为 application-session.xml




    


    
    
    
    



4.测试代码

新建 LoginServlet.java

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {


        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;


        request.getSession().setAttribute("testKey", "[email protected]");

        request.getSession().setMaxInactiveInterval(10*1000);

        response.sendRedirect(request.getContextPath() + "/session");

    }

}

新建 SessionServlet.java

@WebServlet("/session")
public class SessionServlet extends HttpServlet {

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        System.out.println(request.getRemoteAddr());
        System.out.print(request.getRemoteHost() + " : " + request.getRemotePort());

        String sesssionID = request.getSession().getId();
        System.out.println("-----------tomcat2---sesssionID-------" + sesssionID);

        String testKey = (String)request.getSession().getAttribute("testKey");
        System.out.println("-----------tomcat2-testKey-------" + testKey);

        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.append("tomcat2 ---- sesssionID : " + sesssionID);
            out.append("{\"name\":\"dufy2\"}" + "\n");
            out.append("tomcat2 ----- testKey : " + testKey + "\n");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(out != null){
                out.close();
            }
        }

    }

}

效果演示

1.启动Redis,默认端口6379就行!

2.配置Nginx,启动Nginx

Nginx的配置,轮询方式:

#user nobody;
worker_processes 1;
events{
    worker_connections 1024;
    }
http{
    upstream myproject {
        server 127.0.0.1:8888;
        server 127.0.0.1:9999;

    }
    server {
        listen 8080;
        server_name localhost;

        location / {
            proxy_pass http://myproject;
            }
        }
}

3.启动Tomcat1和Tomcat2

将上面搭建好的项目放入两个Tomcat中,分别启动。使用Nginx负载均衡均验证Session是否共享成功!

tomcat1 : http://localhost:8888/
tomcat2 : http://localhost:9999/

访问 http://localhost:8080/ 可以看到,每次刷新页面,请求都分发到不同的Tomcat里面,如图

Spring-Session实现Session共享入门教程_第5张图片
通过Nginx负载到tomcat1

然后使用 http://localhost:8080/login 看到地址栏重定向到/session .发现浏览器返回了数据,进入tomcat2中,然后再次刷新请求进入了tomcat1,发现tomcat2中和tomcat1 sessionId一样,并且在tomcat1中存的testKey,在Tomcat2中也可以获取,不仅SessionId可以共享,其他一些数据也可以进行共享!

Spring-Session实现Session共享入门教程_第6张图片
通过Nginx负载到tomcat2

如何在Redis中查看Session数据,可以使用命令,或者在Windows的RedisDesktopManager中查看!

Spring-Session实现Session共享入门教程_第7张图片
Redis中查看Session信息

key的简单介绍说明:


# 存储 Session 数据,数据类型hash
Key:spring:session:sessions:XXXXXXX

# Redis TTL触发Session 过期。(Redis 本身功能),数据类型:String
Key:spring:session:sessions:expires:XXXXX

#执行 TTL key ,查看剩余生存时间


#定时Job程序触发Session 过期。(spring-session 功能),数据类型:Set
Key:spring:session:expirations:XXXXX


验证成功!

总结

Spring-Session在实际的项目中使用还是比较广泛的,本次搭建采用最简单的配置,基本都是采用官方文档中默认的方式,因为是入门的教程就没有写的很复杂,后面慢慢深入!期待后续的教程吧!

参考文章

使用Spring Session和Redis解决分布式Session跨域共享问题57406162

学习Spring-Session+Redis实现session共享

利用spring session解决共享Session问题


本系列教程

【入门】分布式Session一致性入门简介

【第一篇】Spring-Session实现Session共享入门教程

【第二篇】Spring-Session实现Session共享Redis集群方式配置教程

【第三篇】Spring-Session实现Session共享实现原理以及源码解析


如果您觉得这篇博文对你有帮助,请点下面的喜欢,让更多的人看到,谢谢!

如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!


欢迎访问我的csdn博客,我们一同成长!

不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

博客首页http://blog.csdn.net/u010648555

你可能感兴趣的:(Spring-Session实现Session共享入门教程)