使用Spring-Session共享使用Session
前言:
session共享策略有很多,常见的有粘性复制,高并发下效率查。tomcat-redis-session-manager无疑是一个挺好的方案,缺点要配置tomcat,有点复杂。最优的方案莫过于使用Spring-Session无缝整合redis,只要项目修改即可。
测试项目结构:
项目结构很简单:
Test.java 就是一个页面跳转,传输一下sessionid
@Controller
public class Test {
@RequestMapping("/test")
public String test(HttpSession session, HttpServletRequest request) {
request.setAttribute("id", session.getId());
return "index";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
index.jsp 单纯的打印一下sessionid
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%-- <%@ page isELIgnored ="false" %> --%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'TestUpload.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">
</head>
<body>
我的session:${id}
<br> sessionid=<%=session.getId()%>
</body>
</html>
当项目部署到nginx上的两个tomcat上时,每次访问地址,打印出来的sessionId都发生变化,这样在一些登录的操作中,用户明明在tomcatA上登录了,但是用户的其他操作负载到了TomcatB中,然而B不知道用户已经在A登录了,又让用户登录一次,这样用户体验极差。使用Spring-Session就是把用户的session缓存到redis中,让大家都从redis中获取用户session,这样就保证了session的共享。
使用Spring-Session
- pom.xml 增加依赖
<!-- 使用Spring Session来解决Session共享问题 -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.3.0.RELEASE</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>3.5.0.Final</version>
</dependency>
- web.xml增加配置
<!-- 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>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- Spring.xml增加配置
作用是导入redis配置redis.properties,导入新建的一个配置文件spring-session.xml
<context:property-placeholder location="classpath:db.properties,classpath*:redis.properties" ignore-unresolvable="true"/>
...
<import resource="classpath:spring-session.xml"/>
- 1
- 2
- 3
- 新增配置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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 创建名为springSessionRepositoryFilter 的Spring Bean,继承自Filter。 springSessionRepositoryFilter替换容器默认的HttpSession支持为Spring
Session, 将Session实例存放在Redis中 -->
<bean id="redisHttpSessionConfiguration"
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />
<!-- 使用LettuceConnectionFactory -->
<bean
class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory">
<property name="hostName" value="${redis.ip}" />
<property name="port" value="${redis.port}" />
<property name="password" value="${redis.password}" />
</bean>
<!-- 也可以将使用LettuceConnectionFactory改成使用JedisConnectionFactory,两者保留其一就好 -->
<!--<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> -->
<!--<property name="hostName" value="${redis.ip}"/> -->
<!--<property name="port" value="${redis.port}"/> -->
<!--<property name="password" value="${redis.password}"/> -->
<!--</bean> -->
<!-- 让Spring Session不再执行config命令 -->
<!-- <util:constant
static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP" /> -->
</beans>
- 增加redis.properties
redis.ip=193.112.76.194
redis.port=6379
redis.password=xxxxxx
redis.pool.maxTotal=10
redis.pool.minIdle=4
redis.pool.maxIdle=8
redis.pool.testOnBorrow=true
发布到服务器上。访问index页面。无论刷新多少次结果都一样。session没变
我的session:a4b2fe35-aaa5-40c2-a7de-b1d60180ca04
sessionid=a4b2fe35-aaa5-40c2-a7de-b1d60180ca04
使用redis客户端查看
刚好有个seession一致。
原理:
DelegatingFilterProxy拦截器拦截, springSessionRepositoryFilter替换容器默认的HttpSession支持为SpringSession每个请求都会访问它。
使用Spring-Session共享使用Session的更多相关文章
- Tomcat 集群 + Redis Session 共享出现 Session 瞬间失效问题
写在前面的话 写这篇博客出于公司最近要迁移到新的云上面且对之前的资源,架构做一个升级. 本来是一个不大的项目,旧环境旧一个 TOMCAT 跑起来,不过出于高可用考虑,新环境决定使用 TOMCAT 集群 ...
- shiro源码篇 - shiro的session共享,你值得拥有
前言 开心一刻 老师对小明说:"乳就是小的意思,比如乳猪就是小猪,乳名就是小名,请你用乳字造个句" 小明:"我家很穷,只能住在40平米的乳房" 老师:" ...
- Shiro权限管理框架(二):Shiro结合Redis实现分布式环境下的Session共享
首发地址:https://www.guitu18.com/post/2019/07/28/44.html 本篇是Shiro系列第二篇,使用Shiro基于Redis实现分布式环境下的Session共享. ...
- 用redis实现TOMCAT集群下的session共享
上篇实现了 LINUX中NGINX反向代理下的TOMCAT集群(http://www.cnblogs.com/yuanjava/p/6850764.html) 这次我们在上篇的基础上实现session ...
- 关于session共享的解决方法
当网站业务规模和访问量的逐步增大,原本由单台服务器.单个域名组成的网站架构可能已经无法满足发展需要 此时会购买更多的服务器,并且以频道化的方式启用多个二级子域名,然后根据业务功能将网站分别部署在独立的 ...
- Session的使用与Session共享问题
Session的使用与Session共享问题 Session方法 getId():获取sessionId,这个id不一定是数字,比方说它用字符串来表示唯一标识,所以它返回值是String; boole ...
- 如何实现集群中的 session 共享存储?
Session 是运行在一台服务器上的,所有的访问都会到达我们的唯一服务器上,这 样我们可以根据客户端传来的 sessionID,来获取 session,或在对应 Session 不 存在的情况下(s ...
- 基于Spring Boot/Spring Session/Redis的分布式Session共享解决方案
分布式Web网站一般都会碰到集群session共享问题,之前也做过一些Spring3的项目,当时解决这个问题做过两种方案,一是利用nginx,session交给nginx控制,但是这个需要额外工作较多 ...
- [Spring] spring-session + JedisPool 实现 session 共享
1.至少导入四个jar包: jedis spring-session spring-data-redis commons-pool2 2.bean配置 <?xml version="1 ...
- 单点登录实现(spring session+redis完成session共享)
一.前言 项目中用到的SSO,使用开源框架cas做的.简单的了解了一下cas,并学习了一下 单点登录的原理,有兴趣的同学也可以学习一下,写个demo玩一玩. 二.工程结构 我模拟了 sso的客户端和s ...
随机推荐
- Android最简单的实例 :环境搭建及HelloWorld
Android开发之旅:环境搭建及HelloWorld 2010-04-12 00:45 by 吴秦, 883961 阅读, 140 评论, 收藏, 编辑 ——工欲善其事必先利其器 引言 本系列适合 ...
- D. Artsem and Saunders 数学题
http://codeforces.com/contest/765/problem/D 这题的化简,不能乱带入,因为复合函数的带入,往往要严格根据他们的定义域的 题目要求出下面两个函数 g[h(x)] ...
- OAuth2.0认证流程是如何实现的?
导读 大家也许都有过这样的体验,我们登录一些不是特别常用的软件或网站的时候可以使用QQ.微信或者微博等账号进行授权登陆.例如我们登陆豆瓣网的时候,如果不想单独注册豆瓣网账号的话,就可以选择用微博或者微 ...
- css3 transform + deviceorientation实现图片旋转效果
1. 陀螺仪deviceorientation的使用,参考<关于陀螺仪deviceorientation>https://segmentfault.com/a/11900000071838 ...
- 21全志r58m平台的framework在使用过程中会莫名的崩溃掉
21全志r58m平台的framework在使用过程中会莫名的崩溃掉 2018/10/25 16:20 版本:V1.0 开发板:SC5806 1.系统编译: rootroot@cm88:/home/ww ...
- openmv第一次调试
2018-09-19 20:14:51 import sensor, image, time import car import json import time from pyb import U ...
- SQL——时间戳
mysql 低版本,date.datetime.timestamp 无法精确到毫秒 可以舍弃时间类型字段,用 bigint 来代替,如果用字符串类型代替,还是比较担心排序的时候只是根据第一个字母进行排 ...
- Delphi win10 asssertion failure
Delphi2007 原来安装在Win7 下 运行正常, 自从升级到Win10 ,新建工程运行然后关闭报错, 报错信息如下: ---------------------------bds.exe - ...
- vue路由细节探讨
1.使用router-link 不会让页面刷新,使用a标签会使页面刷新.2.router-link 里面的to="/路由地址" tag=""自定义标签" ...
- iTOP-4418/6818开发板支持锂电池供电方案
iTOP-4418/6818开发板支持的是官方推荐的AXP228电池管理,动态调频,更稳定可靠,支持充放电电路与电量计(库化计), 广泛应用于各种电子产品中. 4418开发板中锂电池充放电接口,适用于 ...