小结
对Spring Session Data Redis和Redisson进行了测试,将Http Session存于Redis中,这样同一个应用的多个实例与Http请求可以解藕,任意一个实例可以处理每一个请求的多个步骤,不会丢失中间状态,达到了想要的效果。
Spring Session Data Redis
实际上开启Spring Session Data Redis
相对比较容易,Redis设置不多说。主要讲一下Sprng Boot,我使用的是gradle,添加以下行:
dependencies {
implementation("org.springframework.session:spring-session-data-redis")
implementation('org.springframework.boot:spring-boot-starter-data-redis')
...
在application.properties中添加:
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=xxxxxx
在主应用中添加以下注解:
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@EnableRedisHttpSession
测试成功,使用办法与普通的Http Session方法是一样的,不需对代码做改动,也就是如下使用方法:
HttpSession session = httpServletRequest.getSession(false);
session.setAttribute("SessionState", testObject);
...
testObject = (testObject) session.getAttribute("SessionState");
通过Another Redis Desktop Manager
是可以看到在Redis中存放的Session的内容的。注意,
- 所有的在Redis中存放的对象需要实现Serializable接口。
public class testObject implements Serializable {
...
- Redis中存放的Session有三个Key-Value对:Session ID, Session Expire Time and Session Detail. 参考第一点,Redis的Session中存放的对象需要实现Serializable接口
- @EnableRedisHttpSession这个注解中的redisFlushMode模式如果配置, 默认模式是ON_SAVE,是不会立即同步的, (表示在response commit前刷新缓存)如果配置为IMMEDIATE模式,会立即将创建的RedisSession同步到Redis中去。
Redisson
Redisson相当于提供了一个封装包供用户使用,省去了很多麻烦,例如不用管Serializable接口,以及更好的效率,由其是有大量的对象存在Redis中的时候。
通过Redisson可以创建Live Object,可以在不同的线程或者虚拟机JVM之间共享Live Object.
以下注意可以使用Live Object,
import org.redisson.api.annotation.REntity;
import org.redisson.api.annotation.RId;
@REntity
public class testObject implements Serializable {
...
@RId
String sessionID;
@Rindex
String Value;
@Rindex可以根据这个创建索引的成员变量进行搜索。
创建Redisson服务后,可以对对象进行存储,例如:
public void storeSession(testObject testObject) {
testObject_1 = service.persist(testObject);
service.asRMap(testObject).expire(500, TimeUnit.SECONDS);
}
public testObject retrieveSessionwID(String sessionID){
return service.get(testObject.class, sessionID);
}
这样就可以使用以上创建的方法存储和提取在Redis中的对象了。Redisson的使用众说纷纭,有人抱怨Redisson在大数据量下性能其实并不好。参考Why should be careful about using Redisson live object service?
注意, 不管是Spring Session Data Redis还是Redisson操作Redis,都不能在存储的对象里有其它操作数据的方法,亲测操作方法并没有更改到Redis中的数据,最好在Redis外面操作数据,操作完成后,再保存到Redis中去。普通的Getter和Setter方法是可以正常使用的。
参考
Redisson: What is Spring Session?
Stackoverflow: Difference between spring httpsession and tomcat session
Spring Documentation: Spring Session – Spring Boot
Github: SympathyForTheDev
s/pring-boot-session-redisson/src/main/java/com/devwantjusthavefun/springbootsessionredisson/config/
Baeldung: A Guide to Redis with Redisson
Redisson: 9.2. Live Object service的说明
Redisson Pro版本
Github: Redis based Tomcat Session Manager
Github: Redisson examples
Why should be careful about using Redisson live object service?
cnblog: SpringBoot+Spring Session+Redis实现Session共享及踩坑记录
简书: 分布式Session(Spring-session-data-redis)
spring boot + redis实现session共享
CSDN: springboot基于redis配置session共享
一篇文章认清Spring-Redis-Session机制
SpringBoot 整合 Spring-Session 实现分布式会话(实战篇)
Spring boot 将 Session 放入 Redis
Stackoverflow: spring framework spring-data-redis serialization exception
cnblog: Consider defining a bean of type ‘org.springframework.data.redis.connection.RedisConnectionFactory’ in your configuration
Github: spring boot 2.0 整合 redis
Serializable Interface in Java
Basic Java Deserialization (ObjectInputStream, readObject)