SpringBoot2.1.4快速整合session-redis实现分布式session共享,极少配置

SpringBoot2.1.4与redis、springsession

  • 集成redis
  • 集成spring-session-Redis
      • 实验效果:
  • 开箱即用的便利

集成redis

1.引入jar包

   
	
		org.springframework.boot
		spring-boot-starter-data-redis
	

2.配置属性
在application.properties增加Redis服务的相关信息

#################redis单服务基础配置#################
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.password=
spring.redis.port=6379

3. RedisTemplate配置

   /**
	 * RedisTemplate配置
     */
	@Bean
	public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
		// 设置序列化
		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);
		// 配置redisTemplate
		RedisTemplate redisTemplate = new RedisTemplate();
		redisTemplate.setConnectionFactory(lettuceConnectionFactory);
		RedisSerializer stringSerializer = new StringRedisSerializer();
		redisTemplate.setKeySerializer(stringSerializer);// key序列化
		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
		redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
		redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
		redisTemplate.afterPropertiesSet();
		return redisTemplate;
	}
 
  

不配置RedisTemplate,也是可以自动注入StringRedisTemplate进行redis的读写操作,但是不能注入 RedisTemplate对象,这里先配置了 RedisTemplate来操作redis

4. 注入RedisTemplate,开始使用操作Redis

@RequestMapping(path = "/redis" )
public class RedisController {
    @Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Autowired
	private RedisTemplate redisTemplate;
       /**
	 * stringRedisTemplate 传入对象
	 * @return
	 */
	@GetMapping("/test2")
	public UUser testRedis2() {
		UUser user = new UUser();
		user.setUserName("test2");
		user.setEmail("11费@QQ.com");
		stringRedisTemplate.opsForValue().set("A2", JSONObject.toJSONString(user));
		UUser stu1 = JSONObject.parseObject(stringRedisTemplate.opsForValue().get("A2"), UUser.class);
		return stu1;
	}

	/**
	 * redisTemplate传入对象
	 * @return
	 */
	@GetMapping("/test1")
	public UUser testRedis1() {
		UUser user = new UUser();
		user.setUserName("test1");
		user.setEmail("11飞@163.com");
		redisTemplate.opsForValue().set("A1", user);
		UUser stu1 = (UUser) redisTemplate.opsForValue().get("A1");
//		redisTemplate.delete("A1");
		return stu1;
	}
}

通过localhost:8080/redis/test1、localhost:8080/redis/test2来进行验证

5.可配置连接池

        
			org.apache.commons
			commons-pool2
		

Jedis与Lettuce的区别:
Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接
Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
springboot2.0后将之前的jedis已经改成Lettuce,默认使用Lettuce

集成spring-session-Redis

参考 https://blog.csdn.net/qq_35206261/article/details/82289066
1 引入jar包

         
			org.springframework.session
			spring-session-data-redis
		

2 配置

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1900)
public class RedisSessionConfig {


}

application.properties增加

spring.session.store-type=redis

也可不进行配置,都有默认值,开箱即用。
这里的maxInactiveIntervalInSeconds设置还没生效,原因还在寻找中。
3 测试session共享

@RestController
@RequestMapping(path = "/redis" )
public class RedisController {
	/**
	 * session测试
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/session", method = RequestMethod.GET)
	public Map addSession (HttpServletRequest request){
		String sessionId = request.getSession().getId();
		String requestURI = request.getRequestURI() + ":"  +  request.getServerPort();
		// 向session中保存用户信息 key规则: user + "_" + uid
		request.getSession().setAttribute("user_1", "{uid:1,username:[email protected]}");


		Map sessionInfoMap = new HashMap<>(2);
		sessionInfoMap.put("sessionId", sessionId);
		sessionInfoMap.put("requestURI", requestURI);
		return sessionInfoMap;
	}

	/**
	 * session测试
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/getSession", method = RequestMethod.GET)
	public Map getSession (HttpServletRequest request){
		String sessionId = request.getSession().getId();
		String requestURI = request.getRequestURI() + ":"  +  request.getServerPort();

		Map sessionInfoMap = new HashMap<>(2);
		// 获取session中uid为1的用户的信息
		String user_1 = (String) request.getSession().getAttribute("user_1");

		sessionInfoMap.put("sessionId", sessionId);
		sessionInfoMap.put("requestURI", requestURI);
		sessionInfoMap.put("user_1", user_1);
		return sessionInfoMap;
	}
}

分别启动不同的端口号,使用浏览器、postman、rest client测试sessionID

结果:使用同一工具,例如postman测试不同端口号请求,其sessionId值一致,并且能从一个端口获取另一个端口存在request中的user信息。session数据存放在redis中

1.8080端口往session中放入对象
SpringBoot2.1.4快速整合session-redis实现分布式session共享,极少配置_第1张图片
2.8081端口请求session中对象
SpringBoot2.1.4快速整合session-redis实现分布式session共享,极少配置_第2张图片

实验效果:

sessionId一致,且成功获取了session中对象,不同端口间session实现共享

开箱即用的便利

注释掉第二步集成spring-session-Redis后的配置,只导入jar包进行测试,其session还是存入了Redis中,结果如上面二图所示,跟增加配置后的效果一致

将引入spring-session-Redis jar包也注释掉 进行测试,也就是回到没集成session-redis前,如下图所示,此时session不再存放在Redis中,且不同端口号之间的session不互通,相同端口session也会有过期时间。

1.8080往session中放入对象
SpringBoot2.1.4快速整合session-redis实现分布式session共享,极少配置_第3张图片
2.8081读取session信息
SpringBoot2.1.4快速整合session-redis实现分布式session共享,极少配置_第4张图片
3.8081再次读取session信息(刷新一次)SpringBoot2.1.4快速整合session-redis实现分布式session共享,极少配置_第5张图片
结果:相同端口之间的session共享,不同端口间session隔离
出现上下两种情况是springboot开箱即用的效果,引入jar包后无需配置即可使用。

你可能感兴趣的:(spring)