spring session通过redis存储,实现session共享_spring session redis-程序员宅基地

技术标签: 服务器集群  spring session  

目录

前言

1 准备工作

1.1 spring框架的jar包

1.2 spring session的相关jar包

2 具体步骤

2.1 创建项目

2.2 spring mvc的配置

2.3 spring session的配置

2.4 web.xml的配置

3 测试

3.1 创建jsp测试文件

3.2 开始测试


前言

web开发中session一直都是做分布式集群应用时需要解决的一个难题,前面写了tomcat服务器集群的文章,那么集群中怎么实现session共享呢?

让我们回顾一下,Tomcat集群搭建(APACHE+MOD_JK+TOMCAT配置)的session共享是直接通过tomcat自带的复制功能,即访问其中一台tomcat服务器就会在其他配置好的tomcat服务器上各复制一份session,这样的session共享可能会存在一定的延迟,同时若并发量一大的话也会有网络风暴的风险;而Tomcat集群搭建(nginx+tomcat+redis)的session共享是通过第三方redis来存储session来实现的,这种方式以前比较流行,但是这种也是需要依赖于tomcat(需要修改tomcat的context.xml的配置),而且现在官方也没去更新tomcat-redis-session-manager的jar包了(仍然停留在支持tomcat7上,一些自己修改的jar包除外)。

本文我要说的session共享,就是独立于servlet容器、session存储在第三方存储容器redis的spring session。它不用担心并发量大时的网络风暴;不用担心换容器运行时,又需要各种各样的配置;不用担心servlet容器(即这里的tomcat)停止服务了,session就不存在了,用户又得重新登陆的麻烦。因为spring session的实现是在项目的配置,以及代码中的。

在开始之前,让我们先了解一下spring session实现session共享,以及在spring框架中实现的原理。

spring session通过redis来实现多个服务器间的session共享的原理,其实就是将session独立出来不依赖原来的web容器,而是存放到与web容器没有耦合关系的redis容器中,这样即使是任何一台web容器挂了,也不会影响到其中的session,如下图所示:

spring session在spring框架中的实现原理,其实就是在请求request上通过DelegatingFilterProxy代理过滤器封装了一层,将原来存储在容器缓存的session变成存储在redis的session,所以在web.xml中的此filter必须得是在所有filter的前面。具体的web容器加载过程,如下图所示:

 

1 准备工作

这里的准备工作有几点,redis存储容器、spring框架的jar包(需要在spring框架的环境下)和spring session的相关jar包。其中redis存储容器,我就不多说了,网上有很多redis的安装教程,或者参考此处redis的安装

1.1 spring框架的jar包

若你的项目原本就有spring框架的,忽略此准备工作。

注意:这里用的spring都是比较高版本的,最好用本文的相应版本,否则会出现一些版本不合的奇葩错误

commons-logging选择1.2版本:http://commons.apache.org/proper/commons-logging/download_logging.cgi

spring-aop选择5.0.8版本:http://www.mvnrepository.com/artifact/org.springframework/spring-aop

spring-beans选择5.0.8版本:http://mvnrepository.com/artifact/org.springframework/spring-beans

spring-context选择5.0.8版本:http://mvnrepository.com/artifact/org.springframework/spring-context

spring-core选择5.0.8版本:http://mvnrepository.com/artifact/org.springframework/spring-core

spring-expression选择5.0.8版本:http://mvnrepository.com/artifact/org.springframework/spring-expression

spring-web选择5.0.8版本:http://mvnrepository.com/artifact/org.springframework/spring-web

spring-webmvc选择5.0.8版本:http://www.mvnrepository.com/artifact/org.springframework/spring-webmvc

spring-tx选择5.0.8版本:http://mvnrepository.com/artifact/org.springframework/spring-tx

 

1.2 spring session的相关jar包

注意:这里用的spring session都是比较高版本的,最好用本文的相应版本,否则会出现一些版本不合的奇葩错误

commons-pool2选择2.6.0版本:http://commons.apache.org/proper/commons-pool/download_pool.cgi

jedis选择2.9.0版本:http://central.maven.org/maven2/redis/clients/jedis/

spring-data-commons选择2.0.9版本:https://repo.spring.io/libs-release/org/springframework/data/spring-data-commons/

spring-data-redis选择2.0.9版本:https://repo.spring.io/libs-release/org/springframework/data/spring-data-redis/

spring-session-core选择2.0.5版本:http://mvnrepository.com/artifact/org.springframework.session/spring-session-core

spring-session-data-redis选择2.0.5版本:https://repo.spring.io/libs-release/org/springframework/session/spring-session-data-redis/

 

2 具体步骤

2.1 创建项目

(1)在eclipse中创建一个web项目,命名为SpringSession。

(2)将上面下载的jar包全放到项目中WEB-INF/lib目录下。

 

2.2 spring mvc的配置

(1)在源码的src目录下创建config放置配置文件的包,以及创建com.sky.springsession放置java源码的包。

(2)在config包下创建applicationContext.xml文件,放置如下代码

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"    
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd 
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.sky.springsession"/>
    
    <context:annotation-config/>

</beans>

这是spring mvc的最基本的配置,当然这些配置在这里其实也是可以免去的。

 

2.3 spring session的配置

在config包下创建spring-session.xml文件,放置如下代码

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="10"/><!-- 最大空闲连接数, 默认8个 -->
        <property name="maxTotal" value="20"/><!-- 最大连接数, 默认8个 -->
        <property name="blockWhenExhausted" value="true"/><!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
        <property name="maxWaitMillis" value="1000"/><!-- 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1 -->
        <property name="testOnBorrow" value="true"/><!-- 在获取连接的时候检查有效性, 默认false -->
    </bean>
    
    <!-- redis连接配置,依次为主机ip,端口,密码,是否使用池,连接池配置引用 -->
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
        p:host-name="192.168.17.132" p:port="6379" p:password="123456" p:usePool="true" p:pool-config-ref="jedisPoolConfig">
    </bean>
    
    <!-- 配置spring-session -->
    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <!-- session过期时间,单位是秒 -->
        <property name="maxInactiveIntervalInSeconds" value="30"></property>
    </bean>
</beans>

注意,用了spring session后,在web.xml设置的session过期时间是无效。因为此session已经不是原来的存储在容器缓存内的session了,而是被封装多了一层后存储在redis的session。

 

2.4 web.xml的配置

在web.xml文件添加如下代码

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:config/*.xml</param-value>
  </context-param>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  

  <!-- spring session的过滤器配置,注意此过滤器必须放在其他过滤器之前 -->
  <filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- springmvc配置 -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 通过初始化参数,指定xml文件的位置 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:config/applicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

配置至此,就能够实现spring session通过存储到redis的session共享了。

 

3 测试

3.1 创建jsp测试文件

(1)在WebContent目录下创建index.jsp,放置如下代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Date" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>spring session</title>
</head>
<body>
<%
System.out.println(new Date()+"=============tomcat1=================");
session.setAttribute("tomcat1", "I am tomcat1");
%>

<h1>hello world!</h1><br>
<p><%=session.getId()%>======<%=new Date()%></p>
<p>tomcat1======<%=session.getAttribute("tomcat1")%></p>
<p>tomcat2======<%=session.getAttribute("tomcat2")%></p>
</body>
</html>

 

(2)在WebContent目录下创建result.jsp,放置如下代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Date" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>spring session</title>
</head>
<body>
<h1>result tomcat1</h1><br>
<p><%=session.getId()%>======<%=new Date()%></p>
<p>tomcat1======<%=session.getAttribute("tomcat1")%></p>
<p>tomcat2======<%=session.getAttribute("tomcat2")%></p>
</body>
</html>

 

3.2 开始测试

(1)打开浏览器,输入url:http://localhost:8080/SpringSession/

 

(2)打开第二个标签页

 

(3)待30秒过后,刷新第二个标签页,发现tomcat1已经为null,说明上面的spring session的过期时间设置是有效的。

 

(4)当然想要看下spring session是否真的存在了redis,也可以到redis客户端上查看。

 

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_15092079/article/details/81939799

智能推荐

概率论总结_p(∪n i=1ai) ≤ pn i=1 p(ai)-程序员宅基地

文章浏览阅读823次,点赞2次,收藏13次。随机事件与概率基本概念随机试验试验可以在相同的条件下重复进行试验所有可能结果是明确可知道的,并且不止一个每一次试验会出现哪一个结果,事先并不确定事件随机事件A,B,C...A,B,C...A,B,C...必然事件Ω\OmegaΩ不可能事件∅\varnothing∅样本空间样本点:随机试验的每一个可能结果称为样本点,记为ω\omegaω样本空间:样本点的全体组成的集合称为样本空间,记为Ω\OmegaΩ基本事件:由一个样本点构成的事件称为基本事件随机事件AAA是由若干个基本_p(∪n i=1ai) ≤ pn i=1 p(ai)

Nuxt中使用Vuex(新版,简单入门)_nuxt vuex-程序员宅基地

文章浏览阅读8.5k次,点赞2次,收藏17次。1.前言因为我学的是后端开发,前端不是很厉害,如果有什么不对的地方请评论指出,谢谢!看这篇文章你需要对Vuex有一定的了解 官方链接做课设的时候使用到了Nuxt框架,需要做登录,也就结识了Vuex,其实以前就学过Vuex,但是一直不知道这个东西有什么优势,特点。这次我在实际使用中就用到了一个非常好用的特点,官方的解释如下:Vuex 的状态存储是响应式的。当 Vue 组件从 store ..._nuxt vuex

vue点击按钮改变按钮样式_vue点击按钮切换样式-程序员宅基地

文章浏览阅读3.7k次。【代码】vue点击按钮改变按钮样式。_vue点击按钮切换样式

图论学习-最短路模型-程序员宅基地

文章浏览阅读2k次,点赞20次,收藏44次。这里只是我对于最短路模型学习的一个记录,不正确的地方希望大家指出。文章目录最短路模型一、 什么是最短路?1.1 概念1.2 基本术语二、主要模型2.1 dijkstra2.1.1 步骤2.1.2 画图理解2.1.3 为什么dijkstra不能处理负权边?2.2 堆优化的dijkstra2.3 bellman_ford2.3.1 三角形不等式2.3.2 步骤2.3.3 代码实现2.4 spfa2.4.1 步骤2.4.2 代码实现2.4.3 主要问题2.5 floyd三、练习题目四、参考最短路模型一、 什_最短路模型

20210409因为内存条的兼容问题引起的编译aosp10莫名的异常_aosp 编译 segmentation fault-程序员宅基地

文章浏览阅读2.7k次。20210409因为内存条的兼容问题引起的编译aosp10莫名的异常内存使用2条32GB的内存条(3000MHz)https://item.jd.com/10025021240070.html酷兽(CUSO)ddr4 32g台式机内存 32g 3000MHz 酷兽夜枭系列【京选存储.稳定兼容】酷兽存储.实惠装机能手(内存终身保固.以换代修)京 东 价¥ 769.00 降价通知32g 3000MHz电脑使用的:dell的Inspiron-3880rootroot@rootroot-Ins_aosp 编译 segmentation fault

SSL_1072&&P2347【砝码称重】-程序员宅基地

文章浏览阅读72次。砝码称重题目设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=1000),要求:输入方式:a1 a2 a3 a4 a5 a6(表示1g砝码有a1个,2g砝码有a2个,…,20g砝码有a6个)输出方式:N(N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)Sample Input1 1 0 0 0 0(注:下划线表示空格)Sample Output3//表示可以称出1g,2g,3g三种不同的重量。解析啊就这?!堂堂1996年分区联赛提高组第

随便推点

BZOJ 2301 [HAOI2011]Problem b(莫比乌斯反演)_[bzoj2301][haoi2011]-程序员宅基地

文章浏览阅读139次。题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2301咱也不知道莫比乌斯函数,莫比乌斯反演怎么来的,直接用就得了...①莫比乌斯函数:else表示质因子分解后有质因子出现一次以上莫比乌斯函数跟着欧拉筛跑一遍就可以求出来②莫比乌斯反演的两种写法:其中f(i)是题目询问的东西,你发现直接求求..._[bzoj2301][haoi2011]

SpringBoot多文件压缩包下载(多附件zip格式)_springboot下载多个文件-程序员宅基地

文章浏览阅读7.4k次。文章目录前言 : 此 Demo 为 Windows 环境下演示,部署到服务器的话路径需改成服务器的路径。一、自定义工具类DownLoadZipUtil二、Dao层分析与sqlmapper层代码(DAO)三、Service层代码三、Controller层代码注意 : 文件的打包下载这里用到了临时路径,下面只需要关注方法ZipTempDownLoad即可,下面的代码实际需根据自己的逻辑需求去写。四、前端部分代码,此Demo前端用的vue五、效果展示前言 : 此 Demo 为 Windows 环境下演示,部_springboot下载多个文件

meta SEO(给搜索引擎看的meta标签 name keywords)_搜索 <meta name="keywords" content="氢能源、燃料、电池技术、清洁能源-程序员宅基地

文章浏览阅读1.8k次。<!-- 你挂载到域名上才有用 --> <meta name="keywords" content="游戏,音乐,体育">_搜索

CVPR2019 主动学习方面论文_cvpr 2019 active learning-程序员宅基地

文章浏览阅读498次。1 Learning Loss for Active Learning 论文下载直接预测样本的LossCVPR2019 论文接受列表_cvpr 2019 active learning

通信原理chapter2总结(内含多径效应和多普勒效应MATLAB仿真)_多普勒效应和多径效应 建模-程序员宅基地

文章浏览阅读4.8k次,点赞12次,收藏67次。第二章总结1.信道:通信系统中信道是指发送设备到接收设备之间信号传输的通道,是通信系统中的一个重要组成部分。2.分类:1)按照传输媒介:无线信道和有线信道;2)根据信道研究对象不同:调制信道,编码信道3)按照信道的冲激响应是否随时间变化:恒参信道,随参信道4)按照信道输入和输出符号是否离散:离散信道,连续信道3. 简介1)有线信道:利用人造的传导电或光信号的媒质来传输信号,如明线,..._多普勒效应和多径效应 建模

富士通01018z平板电脑评测_微软Surface Pro 7详细评测:仍旧是最好的二合一平板电脑...-程序员宅基地

文章浏览阅读1k次。今年10月初,当人们还沉浸在国庆放假的喜悦中的时候,大洋彼岸的微软在纽约召开新品发布会,一口气发布了6款Surface设备,除了惊艳的双屏电脑Surface Neo以及传说中的“Surface Phone”以不一样的形态和消费者见面之外,升级版的微软Surface Pro 7也是本次发布会的最大看点之一,微软Surface Pro 7跟着英特尔的节奏升级到了10代酷睿处理器,另外的一个看点则是增加..._farq01018z

推荐文章

热门文章

相关标签