java分布式会话redis_详解springboot中redis的使用和分布式session共享问题
对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash、轮训、根据权重、随机等。不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因此会出现session不同步或者丢失的问题。
实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat、Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中。
本文旨在解决分布式系统的session如何共享问题,大致思路:session放入redis。其他解决方案:持久化、放cache等都可以,但是自从有了redis,这完全可以变的简简单单。
本文大致分两步:
1.springboot中如何使用redis。
2.redis如何解决session共享
pom依赖
org.springframework.boot
spring-boot-starter-redis
org.springframework.data
spring-data-redis
${spring-data-redis.version}
redis.clients
jedis
${jedis.version}
org.springframework.session
spring-session-data-redis
添加redis配置类
该配置类同样可以配置缓存失效时间等。
package com.mos.quote.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
/**
* @author Administrator
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public KeyGenerator KeyGenerator(){
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
};
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//设置缓存过期时间
rcm.setDefaultExpiration(600000);
return rcm;
}
}
配置redis服务
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=192.168.1.118
# Redis服务器连接端口
spring.redis.port=6381
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0
单元测试
1、set值(字符串)
@Test
public void put(){
stringRedisTemplate.opsForValue().set("test001","test001");
Assert.assertEquals("test001", stringRedisTemplate.opsForValue().get("test001"));
}
往redis放一个key为test001、value为test001的值,然后查看redis
key=test001
2、set值(object)
@Test
public void testObj() throws Exception {
SysUser user=new SysUser();
user.setId("123456");
user.setName("张三");
ValueOperations operations=redisTemplate.opsForValue();
operations.set("user1", user);
operations.set("user2", user,5, TimeUnit.SECONDS);
Thread.sleep(6000);
Assert.assertFalse(redisTemplate.hasKey("user2"));
}
往redis分别放key为user1和user2的对象,user2设置5秒失效,线程等待6秒再完成,期望结果:redis中有user1,没有user2,bingo!!!
ObjTest
解决session共享
使用spring-session-data-redis实现session共享,pom中引入该依赖(上文已添加),添加SessionConfig配置类。
对,没看错,只需要这个就够了。最长有效时间根据自己情况随意配置即可。
package com.mos.quote.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
* @author Administrator
*/
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3000)
public class SessionConfig {
}
测试
写一个简单Controller,如下
@RequestMapping("testSessionTimeOut")
public String testSessionTimeOut(String id,HttpSession session,Model model){
Area area = areaService.getById(id);
System.out.println("sessionId-------->"+session.getId());
model.addAttribute("area",JSON.toJSONString(area));
session.setAttribute("area",JSON.toJSONString(area));
return "demo/test1";
}
这里可以看到sessionId:
sessionId
看redis中,可以看到失效时间,sessionId等
sessionId
共享session
另外找一个机器,照着这个配置再来一遍,自动启用session共享,因为sessionId都存在了同一个redis中。奏是这么简单。挽起袖子开始干吧。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
java分布式会话redis_详解springboot中redis的使用和分布式session共享问题相关推荐
- java 拦截指定jsp_详解Struts2中对未登录jsp页面实现拦截功能
struts2中拦截器大家都很经常使用,但是拦截器只能拦截action不能拦截jsp页面.这个时候就有点尴尬了,按道理来说没登录的用户只能看login界面不能够通过输入url进行界面跳转,这显然是不合 ...
- java 标量替换_详解jvm中的标量替换
概述 通常在java中创建一个对象,大家都认为是在堆中创建. 在jdk6开始有逃逸分析,标量替换等技术,关于在堆中创建对象不再绝对. 关于标量替换,通过以下几点进行概述: 逃逸分析 标量替换是什么 测 ...
- 详解SpringBoot整合Redis
SpringBoot整合Redis 在SpringBoot中一般使用RedisTemplate提供的方法来操作Redis.那么使用SpringBoot整合Redis 需要那些步骤呢. 1.JedisP ...
- RedisTemplate操作redis五大类型用法详解(springboot整合redis版本)
1.案例说明 springboot整合redis之后,提供了操作redis的简便方式 通过通用对象redisTemplate方式操作String,Hash,List,Set SortSet五大数据类型 ...
- java 内存跟踪_详解JVM中的本机内存跟踪
1.概述 有没有想过为什么Java应用程序通过众所周知的-Xms和-Xmx调优标志消耗的内存比指定数量多得多?出于各种原因和可能的优化,JVM可以分配额外的本机内存.这些额外的分配最终会使消耗的内存超 ...
- java restful接口测试_详解SpringBoot restful api的单元测试
现在我们来利用Spring Boot来构建一个RestFul API,具体如下: 1.添加Springboot测试注解 @RunWith(SpringRunner.class) @SpringBoot ...
- springboot中的spring-session用mysql实现session共享实践
1.pom.xml添加依赖: <!-- 数据库session管理 --> <dependency><groupId>org.springframework.sess ...
- Java编程配置思路详解
Java编程配置思路详解 SpringBoot虽然提供了很多优秀的starter帮助我们快速开发,可实际生产环境的特殊性,我们依然需要对默认整合配置做自定义操作,提高程序的可控性,虽然你配的不一定比官 ...
- 【视频】详解Scala中的类及与Java的详细区别
详解Scala中的类及与Java的详细区别
最新文章
- 华为机考HJ6求质因子C语言解法
- 进阶学习(3.12) Operand Pattern 装饰器模式
- QT如何让窗口放置在屏幕正中间
- python安装以及版本检测
- FreeRTOS互斥锁
- 使用javascript在客户端获取URL参数值的函数
- evt参数是干啥用的_塑料凳子上的洞,是干啥用的?
- electron forge 好用吗_在优麒麟上使用 Electron 开发桌面应用
- 解决MacOS升级后出现xcrun: error: invalid active developer path, missing xcrun的问题
- tessnet2 在vs2010 及以上版本不能调用的解决方案
- 如何进行linux内核开发,2. 开发流程如何工作 — The Linux Kernel documentation
- linux shell并发执行命令
- Alex 的 Hadoop 菜鸟教程: 第3课 Hadoop 安装教程 - 非HA方式 (一台server)
- 我的世界如何安装java环境变量_JDK安装与环境变量配置方法
- 并行强化学习算法:A2C/A3C
- vue自定义数字键盘
- Arduino基础与常用函数
- SparkEnv源码解读
- 截断二进制指数退避算法c++实现
- 美团数据分析岗面试题分享
热门文章
- find VS not looking for VS2015
- vue中更换标签页.ico图标报错路径找不到图片
- python语言是编译性语音_最强编程语言 Java 和最受欢迎之 Python 的巅峰对决
- tcp实时传输kafka数据_tcp怎么传输大数据
- 一个form 如何做两次提交_如何做一个优秀的家长
- BugkuCTF-WEB题bp
- 用sklearn mysql_Sklearn之Linear Regression
- php加大session,PHP :: Bug #63251 :: yaf session功能增强
- sql数据导入错误代码: 0x80004005_SQL入门第八关 项目实战
- cmd c语言 图形,CMD-C彩图隐写方案