개요
Spring에서 Global session전략을 사용할 때 일반적으로 redis를 사용합니다. Spring redis session을 적용한 이후 실제로 redis에 접속하여 값을 조회할 일은 거의 없습니다. 그렇기 때문에 세션 정보가 redis에 어떤 자료구조로 어떻게 저장되는지 한번 확인해보겠습니다.
간단하게 세션에 값을 저장하는 예제를 만들어 보겠습니다. STS에서 Spring boot starter를 사용하여 간편하게 만들 수 있습니다.
Spring code
해당 프로젝트의 코드는 github에서 모두 확인하실 수 있습니다.
https://github.com/yyy9942/spring-redis-session-exam
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Session data를 redis에 저장하기 위해서는 spring session data redis 의존성을 추가해주어야 합니다.
또한 웹으로 접속하여 session정보를 받을 것이기 때문에 spring boot starter web 의존성도 추가해주세요.
application.properties
spring.session.store-type=redis
spring.redis.host=localhost
spring.redis.password=
spring.redis.port=6379
RedisSessionExamApplication.class
package com.deveric;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@SpringBootApplication
@EnableRedisHttpSession
public class RedisSessionExamApplication {
public static void main(String[] args) {
SpringApplication.run(RedisSessionExamApplication.class, args);
}
}
Redis에 세션 데이터를 저장하기 위해 어노테이션 @EnableRedisHttpSession을 추가해주어야 합니다.
RedisConfig.class
package com.deveric.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@Configuration
public class RedisConfig {
@Value("${spring.redis.password}")
private String redisPwd;
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.registerModules(new JavaTimeModule(), new Jdk8Module());
return mapper;
}
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setPassword(redisPwd);
LettuceConnectionFactory lettuceConnectionFactory =
new LettuceConnectionFactory(redisStandaloneConfiguration);
return lettuceConnectionFactory;
}
}
HelloController.class
package com.deveric.controller;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("hello")
public String hello(HttpSession session) {
session.setAttribute("hello", "eric");
return "hello eric!";
}
}
redis에서 데이터 조회
Postman으로 http://localhost/hello URL을 테스트 했을 때 redis에 다음과 같이 저장됩니다.
해당 데이터의 타입은 각각 다음과 같습니다.
각각 string, set, hash로 하나에 세션은 총 3가지의 데이터 타입으로 저장됩니다.
이 각 데이터는 어떤 것을 의미할까요?
Spring redis session에 세션을 저장하면 조회할 수 있는 데이터 1. spring:session:sessions:expires (string) 2. spring:session:expirations (set) 3. spring:session:sessions (hash) |
일단 세션에 저장한 데이터는 어디에 있을지 유추할 수 있습니다. session은 map을 저장소로 사용하기 때문에 hash에 있을 것이라 판단했습니다. 실제로 데이터가 hash타입 spring:session:sessions에 저장되어 있는지 확인해보았습니다.
실재 hello 정보가 저장되어있는 것을 확인할 수 있었습니다. 데이터를 조회해보겠습니다.
"eric" 이라는 데이터가 저장되어 있는 것을 확인할 수 있었습니다. 나머지 두 가지 데이터는 어떤 데이터를 저장할까요? 공식 문서를 참고하여 어떤 데이터를 저장하는지 참조해보았습니다.
저장 형식 | 자료형 | 역할 |
spring:session:sessions:expires:(session id) |
string | 해당 세션의 만료 키로 사용합니다. |
spring:session:expirations:(expire time) | set | expire time에 삭제될 세션 정보들을 담고있습니다. 해당 time이 되면 저장된 데이터를 조회하여 해당 세션을 모두 삭제합니다. |
spring:session:sessions:(session id) | hash | 세션의 생성 시간, 마지막 세션 조회 시간, 최대 타임아웃 허용 시간과 해당 세션에 저장한 데이터를 저장합니다. |
spring:session:sessions:expires:(session id) 같은 경우는 세션의 만료를 키 자체에서 추적하게 되면 조회가 불가능하기 때문에 사용한다고 합니다. Spring 공식 doc에서는 다음과 같이 설명하고 있습니다.
후기
Spring boot에서 간편하게 설정할 수 있는 redis session이지만 실제 어떻게 저장되는지 확인할 수 있었습니다. 어떤 key에 어떤 데이터가 저장되는지 알았으니 이제 사용자가 언제 접속했는지, 언제 마지막으로 세션이 끝났는지, 어떤 데이터를 저장했는지 더 명시적으로 확인할 수 있을 것입니다.
References
https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-redis.html
https://docs.spring.io/spring-session/docs/current/reference/html5/
'Web > Spring' 카테고리의 다른 글
Spring boot에서 Redis Cache 사용하기 (2) | 2020.05.04 |
---|---|
[Spring] 트랜잭션의 전파 설정별 동작 (11) | 2020.03.04 |
[Spring] Spring은 왜 memcached 대신 Redis를 선택했을까? (4) | 2019.10.22 |
[Spring Mybatis] 중복 쿼리를 include, sql로 대체하기 (0) | 2019.10.16 |
[Spring-boot JPA] 쿼리와 파라미터 확인방법 (0) | 2019.09.09 |
댓글