Projects/hub-eleven

[동시성 처리] RedissonClient Bean 설정 클래스 추가 (1)

annovation 2026. 5. 27. 22:00

RedissonClient

💡RedissonClient 란?

Spring Boot 애플리케이션  --->  Redis 서버
  • Java 애플리케이션에서 Redis/Valkey를 사용할 수 있게 해주는 Redisson의 핵심 클라이언트 객체
  • 즉, Java 코드와 Redis 중간에서 통신을 도와주는 객체
✅ Redisson 의 핵심 '클라이언트' 객체 ?
요청을 받는 쪽 = 서버
요청을 보내는 쪽 = 클라이언트

 

💡예시

Redis 서버
→ 락 정보, 캐시 데이터 등을 저장하고 요청을 처리하는 쪽

Spring Boot 애플리케이션
→ Redis에 "락 잡아줘", "값 저장해줘", "값 조회해줘"라고 요청하는 쪽
  • Spring Boot 안에서 Redis에 요청을 보내는 객체를 Redis client라고 부른다.
  • RedissonClient는 그중에서도 Redisson 라이브러리가 제공하는 클라이언트
redissonClient.getLock("stock:decrease:123");
  • 이건 Java 코드 입장에서는 메서드 호출이지만, 실제로는 RedissonClient가 Redis 서버와 통신해서 분산 락을 사용할 수 있게 해준다.

💡비유

Redis 서버 = 창고
Redisson = 창고를 쓰기 쉽게 해주는 Java 라이브러리
RedissonClient = 창고 출입증 + 창고 직원 호출 창구
RLock = 창고 안에 있는 특정 자물쇠

RedissonClient Bean 설정 클래스 추가

💡product/src/main/java/com/hubEleven/stock/infrastructure/configuration/RedissonConfig.java

@Configuration
public class RedissonConfig {

    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient(
            @Value("${spring.data.redis.host:localhost}") String host,
            @Value("${spring.data.redis.port:6379}") int port) {

        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + host + ":" + port);

        return Redisson.create(config);
    }
}

 

💡역할

  • yml 파일의 Redis host/port 설정을 읽어서
spring:
  data:
    redis:
      host: ${REDIS_HOST:localhost}
      port: ${REDIS_PORT:6379}
  • RedissonClient를 Spring Bean으로 등록
  • 이후 락 구현체에서 RedissonClient를 주입받을 수 있게 함

💡무엇을 적용하는지

  • Spring이 관리하는 RedissonClient Bean을 만든다.
  • 아까 설정한 spring.data.redis.host, spring.data.redis.port 값을 읽는다.
  • Redis 주소를 redis://host:port 형태로 Redisson에 넘긴다.

💡RedissonClient를 직접 new로 만들지 않고, @Bean으로 등록해서 주입받는 이유는?

  • 이후 RedissonStockLockManager에서 RedissonClient를 주입받아야 한다.
  • 매번 락을 쓸 때마다 Redisson.create(...)를 새로 만들면 안 된다.
요청 100개
→ RedissonClient 100개 생성
→ Redis 연결도 100번 준비
→ 내부 리소스도 100번 준비
→ 끝나고 shutdown 안 하면 리소스 누수 가능
  • RedissonClient는 Redis 연결 리소스를 갖는 객체라 애플리케이션 전체에서 하나의 Bean으로 관리해야한다.
애플리케이션 시작
→ RedissonClient 1개 생성
→ Spring이 Bean으로 보관
→ RedissonStockLockManager에 주입
→ 재고 감소 요청마다 같은 RedissonClient 재사용
→ 애플리케이션 종료 시 shutdown
  • destroyMethod = "shutdown"을 넣으면 애플리케이션 종료 시 Redisson 연결도 정상 종료된다.
  • 요약 : RedissonClient를 애플리케이션 전체에서 재사용하고, Spring이 생성/주입/종료까지 관리하게 하려고
✅ Spring Bean
Bean = Spring이 생성하고 관리하는 객체
Spring Container = Bean들을 보관하고 필요한 곳에 주입해주는 공간

 

💡왜 decreaseStock() 안에서 매번 아래처럼 만들면 안 될까?

RedissonClient redissonClient = Redisson.create(config);
  • Redisson 공식 문서에서는 먼저 Config를 만들고, Redisson.create(config)로 RedissonClient 인스턴스를 만든 뒤, 그 인스턴스에서 RLockRMap 같은 Redis 기반 객체를 가져오는 흐름을 보여준다. (Redisson 공식 문서)
  • decreaseStock()은 주문 요청마다 호출되고 그 안에서 매번 Redisson.create(config)를 하면 요청마다 Redis 클라이언트를 새로 만들게 된다.
  • 이 경우의 문제점은 :

1. Redis 연결 리소스를 매 요청마다 생성

Redis 서버 주소 설정
네트워크 연결 준비
connection pool 준비
명령을 보내고 응답을 받는 내부 처리 구조
timeout/retry 설정
내부 스레드 리소스

 

2. 요청마다 Redis 연결 관리자를 새로 만드는 비용이 든다.

  • Redisson.create(config)는 “그냥 객체 하나 생성”이 아니라, Redis를 사용할 준비 세트를 만드는 작업이다.
  • 그래서 요청마다 이걸 만들면 매번 준비 작업을 반복한다.
Redis 서버 주소 확인
Redis와 통신할 네트워크 연결 준비
명령을 보낼 내부 구조 준비
응답을 받을 내부 구조 준비
연결 풀 준비
타임아웃 설정 준비

 

3. 동시 요청이 많을수록 불필요한 객체와 연결 리소스가 늘어난다.

  • 각 RedissonClient는 내부적으로 Redis와 통신할 준비를 한다.
  • 그러면 메모리도 쓰고, 네트워크 연결도 쓰고, 내부 스레드 같은 자원도 쓸 수 있다.

4. 매번 shutdown 해주지 않으면 연결/스레드 리소스가 남을 수 있음

  • RedissonClient 생성 과정을 비유해보자면, RedissonClient 생성 = 호텔 방 하나 빌림
  • 그러면 사용 끝난 뒤 반드시 체크아웃해야 한다.
redissonClient.shutdown();
  • shutdown 안 하면? 사용 안 하는 방이 계속 점유되고, 이 상태가 '리소스가 남는다'는 뜻이다.

5. decreaseStock()이 재고 감소뿐 아니라 Redis 클라이언트 생성 책임까지 갖게 됨

 

6. 테스트에서 RedissonClient를 가짜 객체나 테스트용 락으로 바꾸기 어려워짐

 

❗️따라서 애플리케이션이 시작할 때, RedissonClient 객체 하나를 만들어 Spring Bean 으로 등록해두고 재사용한다.

RedissonClient redissonClient = Redisson.create(config);
  • RedissonClient 객체가 Spring Bean이 됨
  • Spring Container가 이 객체를 보관함
  • 필요한 클래스에 같은 객체를 주입함

출처

1. Redisson Docs : https://redisson.pro/docs/overview/

 

Overview - Redisson Reference Guide

Overview Redisson is the Java Client and Real-Time Data Platform for Valkey and Redis. Providing the most convenient and easiest way to work with Valkey or Redis. Redisson objects provide an abstraction layer between Valkey or Redis and your Java code, whi

redisson.pro

2. Spring Docs : Bean Overview

https://docs.enterprise.spring.io/spring-framework/reference/core/beans/definition.html

 

Bean Overview :: Spring Framework

Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. A bean usually has only one identifier. However, if it requires more than one, the extra ones can be considered aliases. In XML-based configu

docs.enterprise.spring.io

반응형