in Uncategorized

Spring Boot中使用Spring Session Data Redis和Redisson的一些尝试

小结

对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)

Write a Comment

Comment