IT/Live Coding

Spring Boot + Redis로 세션 공유하기 (테스트 영상 & 소스 코드 포함)

어흥꼬비 2025. 3. 5.

Spring Boot + Redis로 세션 공유하기 (테스트 영상 & 소스 코드 포함)

Redis를 활용한 애플리케이션 간 세션 공유 실험! (짧고 간단한 영상)

레디스를 공부한지 얼마 안되어서 까먹기 싫어 기록으로 남긴다.

 

동영상

소스

application.yml

server:
  port: 9090
  servlet:
    context-path: /
    encoding:
      charset: UTF-8
      enabled: true
      force: true
spring:
  devtools:
    livereload.enabled: true
    restart.enabled: true
  datasource:
    driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
    url: jdbc:log4jdbc:mysql://localhost:3309/dbhikari:
      username: 사용자
      password: 비밀번호
      connectionTimeout: 10000
      maximum-pool-size: 15
      max-lifetime: 600000
      readOnly: false
      connection-test-query: SELECT 1

  session:
    store-type: redis   # 세션을 Redis에 저장
    redis:
      namespace: session   # Redis에 저장할 세션 데이터의 네임스페이스
      timeout: 1800  # 세션 타임아웃 (초 단위)

data:
  redis:
    host: localhost   # Redis 서버 주소
    port: 6379        # Redis 포트
    password:         # (필요하면 비밀번호 추가)
    timeout: 6000     # 연결 타임아웃 (ms)
    lettuce:
      pool:
        max-active: 8  # 최대 활성 연결 수
        max-idle: 8    # 최대 유휴 연결 수
        min-idle: 0    # 최소 유휴 연결 수
        max-wait: -1   # 최대 대기 시간 (무제한)

controller

package com.lsy.redisvideo.session.controller;

import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


@RestController
@Slf4j
@RequestMapping("/session")
public class SessionController {

    // 세션에 데이터 저장
    @PostMapping("")
    public String setSession(@RequestParam String key, @RequestParam String value, HttpSession session) {
        session.setAttribute(key, value);  // 세션에 key-value 저장
        return "Session data saved: " + key + " = " + value;
    }

    // 세션에서 데이터 조회
    @GetMapping("")
    public String getSession(@RequestParam String key, HttpSession session) {
        Object value = session.getAttribute(key);  // 세션에서 데이터 조회
        if (value != null) {
            return "Session data: " + key + " = " + value;
        } else {
            return "No data found for key: " + key;
        }
    }

    // 세션 삭제
    @DeleteMapping("")
    public String removeSession(@RequestParam String key, HttpSession session) {
        session.removeAttribute(key);  // 세션에서 데이터 삭제
        return "Session data removed for key: " + key;
    }

    // 세션에 저장된 모든 데이터 출력
    @GetMapping("/list")
    public Map<String, Object> getAllSessionData(HttpSession session) {
        Map<String, Object> sessionData = new HashMap<>();
        Enumeration<String> attributeNames = session.getAttributeNames();

        while (attributeNames.hasMoreElements()) {
            String key = attributeNames.nextElement();
            sessionData.put(key, session.getAttribute(key));
        }

        return sessionData;
    }
}

RedisConfig

package com.lsy.redisvideo.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
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.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableCaching
public class RedisConfig {

    @Value("${data.redis.host}")
    private String host;
    @Value("${data.redis.port}")
    private int port;

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

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        return redisTemplate;
    }
}

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.9'
    id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.lsy'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    // Logging
    implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
    // swagger
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
    // redis
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    // session
    implementation 'org.springframework.session:spring-session-data-redis'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.mysql:mysql-connector-j'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
    useJUnitPlatform()
}

docker-compose.yml

version: '3'

services:
  db:
    image: mysql  
    container_name: mysql
    restart: always
    volumes:
    # 호스트 볼륨 연결
      - ./mysql-data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=1234
      - MYSQL_DATABASE=rootdb
    ports:
      - "3309:3306"

  # Redis 설정
  redis:
    image: redis
    container_name: redis
    restart: always
    volumes:
      - ./redis-data:/data  # Redis 데이터를 위한 볼륨 설정
    ports:
      - "6379:6379"  # Redis 기본 포트 연결

호스트와 볼륨을 연결 했기 때문에 docker-compose.yml이 있는 경로에 mysql-data, redis-data폴더 생성 필요


개인 스터디 기록을 메모하는 공간이라 틀린점이 있을 수 있습니다.

틀린 점 있을 경우 댓글 부탁드립니다.

 

Spring Boot + Redis 캐싱 구현하기 (테스트 영상 & 소스 코드 포함)

Redis를 활용한 캐싱 구현! (짧고 간단한 영상)역시나 레디스 공부한 것 까먹기 싫어 기록으로 남긴다.동영상소스application.ymlserver: port: 9090 servlet: context-path: / encoding: charset: UTF-8 enabled: true force: tru...

yaga.tistory.com

 

Spring Boot + Redis로 실시간 랭킹 구현 (테스트 영상 & 소스 코드 포함)

Redis를 활용한 실시간 랭킹 구현! (짧고 간단한 영상)역시나 레디스 공부한 것 까먹기 싫어 기록으로 남긴다.동영상소스application.ymlserver: port: 8081 servlet: context-path: / encoding: charset: UTF-8 enabled: true...

yaga.tistory.com