Redis를 이용해 Session정보를 공유하자!

Sol's·2023년 2월 2일
0

팀프로젝트

목록 보기
16/25

앞서 Session의 단점과 단점을 보완할 수 있는 Redis서버에 대해 알아보았습니다.

오늘은 Redis에 Session을 저장하여 서버가 다중화되어도 Session정보를 저장 할 수 있게 리펙토링할 것입니다.

Redis 장점

컨테이너 스케일 인, 아웃할때 세션을 공유하여 여러 컨테이너가 필요한 정보들을 추가적인 작업없이 사용 할 수 있습니다.
ex) 서버를 8080, 8081로 띄워놓은 상황에서 8080에서 로그인을 하고 8081로 접속하여도 그대로 로그인이 되어있습니다.

Redis 설치

EC2에 띄워놓은 서버에 Redis를 설치해야합니다.
Docker에서 redis의 이미지를 다운받을 수 있습니다.

레디스 이미지 가져오기

docker pull redis

레디스 서버 실행하기

docker run --name myredis -d -p 6379:6379 redis

Redis 설정

build.gradle에 redis-starter, redis session라이브러리를 추가하고 빌드

  implementation 'org.springframework.boot:spring-boot-starter-data-redis'
  implementation 'org.springframework.session:spring-session-data-redis'

application.yml 에 host 와 port 를 설정
localhost:6379 는 기본값이기 때문에 만약 Redis 를 localhost:6379 로 띄웠다면 따로 설정하지 않아도 연결됩니다

spring:
 redis:
  host: localhost
  port: 6379

Redis 접속방법

Docker의 redis-cli로 접속하기

docker run -it --link myredis:redis --rm redis redis-cli -h redis -p 6379

Configuration

Redis 사용을 위한 기본 Configuration
application.yml 에 설정한 값을 @Value 어노테이션으로 주입.

@Configuration
public class RedisConfig {

  @Value("${spring.redis.host}")
  private String host;

  @Value("${spring.redis.port}")
  private int port;

  @Bean
  public RedisConnectionFactory redisConnectionFactory() {
      return new LettuceConnectionFactory(host, port);
  }
}

RedisTemplate

지금은 사용하지 않지만 나중에 사용할 경우를 대비해 추가했습니다

RedisTemplate 을 사용하면 특정 Entity 뿐만 아니라 여러가지 원하는 타입을 넣을 수 있습니다.
template 을 선언한 후 원하는 타입에 맞는 Operations 을 꺼내서 사용합니다.

@Configuration
@EnableRedisRepositories // redis 활성화
public class RedisConfig {
    @Value("${spring.redis.host}")
    private String redisHost;

    @Value("${spring.redis.port}")
    private int redisPort;

    /*
    RedisTemplate을 이용한 방식

    RedisConnectionFactory 인터페이스를 통해
    LettuceConnectionFactory를 생성하여 반환
     */

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(redisHost, redisPort);
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate() {
        // redisTemplate를 받아와서 set, get, delete를 사용
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        /**
         * setKeySerializer, setValueSerializer 설정
         * redis-cli을 통해 직접 데이터를 조회 시 알아볼 수 없는 형태로 출력되는 것을 방지
         */
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory());

        return redisTemplate;
    }
}

@EnabledRedisHttpSession

Main메서드에 @EnabledRedisHttpSession 어노테이션으로 Redis 세션 사용을 설정합니다.

@SpringBootApplication
@EnableRedisHttpSession
public class PocoapocoApplication {
    public static void main(String[] args) {
        SpringApplication.run(PocoapocoApplication.class, args);
    }
}

생각보다 너무 간단했습니다.
그럼 바로 테스트를 진행해 보겠습니다.

로그인시 Redis 저장소 확인해보기

Docker를 통해 Redis에 접근하여 확인해 보겠습니다.

Docker의 redis-cli로 접속하기

docker run -it --link myredis:redis --rm redis redis-cli -h redis -p 6379


로그인을 하면 redis 서버에 4개의 key가 저장되는것을 확인할 수 있습니다.

1) "spring:session:sessions:expires:$sesssionId (string)

스프링 세션의 만료시간을 관리하는 key입니다.

2) "spring:session:expirations:$expireTime" (set)

스프링 세션의 만료시간입니다.

3) "spring:session:sessions:$sessionId" (hash)

생성된 스프링 세션 데이터입니다.

4) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:$username (set)

username으로 세션을 가져올 수 있도록 저장되는 인덱스입니다.

딱봐도 hash에 세션정보들이 담겨있을것 같다는 생각이 들었습니다.

조회하기

Hash저장소는 key, get명령어 앞에 h를 붙여 사용할 수 있습니다.
지금 사용할 명령어는 hkeys: 해시 키값을 전부 조회, hgetall: 해시 밸류를 전부 조회

세션 정보에 담겨진 정보를 확인해보겠습니다.

로그인시 넣어두었던 JWT의 키값인 Authorization이 확인이 됩니다.

정리

Redis를 활용해 서버마다 Session을 공유하게 만들었습니다.
생각보다 간단하게 Session을 공유할 수 있어서 좋았습니다.

Redis는 백엔드에서 활용도가 높은것 같아 더 알아보고 공부를 해봐야 할것같습니다.

참고자료

Redis를 로그인 Session Storage로 이용하기

profile
배우고, 생각하고, 행동해라

0개의 댓글