Redisson Lock 처리 방법(2)

2024. 12. 30. 18:55IT정보/초보자를 위한 IT 팁

반응형

이번 시간에는 Redisson Lock을 단순히 락으로 사용하는 것을 넘어 공통화하여 코드 중복을 줄이고, 어노테이션 기반으로 더 효율적인 관리를 구현 할 수 있도록 설명 하겠습니다.


 

Redisson Lock의 기본 개념

Redisson Lock은 Redis 기반의 분산 락으로, 분산 환경에서 데이터 동기화 문제를 해결하기 위한 강력한 도구입니다. 다음은 Redisson Lock의 주요 특징입니다:

  • 분산 락 제공: 여러 서버에서 동기화 문제를 방지합니다.
  • 자동 만료 시간: Deadlock을 방지하기 위해 락 해제를 자동으로 처리합니다.
  • 재진입 가능: 동일 스레드에서 여러 번 락을 획득할 수 있습니다.
  • 공정 락 지원: 대기 순서를 보장하여 공정성을 제공합니다.

 

공통화된 Redisson Lock 처리 방법

Redisson 클라이언트 공통화

여러 곳에서 Redisson Lock을 사용할 경우, 클라이언트를 공통화하여 코드 중복을 줄이고 관리 효율성을 높일 수 있습니다.

예제: Redisson 클라이언트 공통화

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.stereotype.Component;

@Component
public class RedissonClientProvider {
    private final RedissonClient redissonClient;

    public RedissonClientProvider() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        this.redissonClient = Redisson.create(config);
    }

    public RedissonClient getClient() {
        return redissonClient;
    }
}
  • RedissonClientProvider는 애플리케이션 전체에서 Redisson 클라이언트를 공통으로 사용하도록 제공합니다.
  • 클라이언트 재생성에 따른 성능 문제를 방지합니다.

공통 락 유틸리티 구현

공통 락 유틸리티를 만들어 Lock 처리 로직을 재사용 가능하게 만듭니다.

예제: 공통 락 유틸리티

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class LockUtil {
    private final RedissonClientProvider redissonClientProvider;

    public LockUtil(RedissonClientProvider redissonClientProvider) {
        this.redissonClientProvider = redissonClientProvider;
    }

    public void executeWithLock(String lockName, Runnable task, long waitTime, long leaseTime) {
        RLock lock = redissonClientProvider.getClient().getLock(lockName);
        try {
            if (lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS)) {
                try {
                    task.run();
                } finally {
                    lock.unlock();
                }
            } else {
                throw new RuntimeException("Failed to acquire lock: " + lockName);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Lock execution interrupted", e);
        }
    }
}
  • executeWithLock 메서드는 락 처리 로직을 캡슐화하여 재사용성 제공
  • 락 이름, 대기 시간, 임대 시간 등을 매개변수로 받아 유연하게 사용할 수 있습니다.


어노테이션을 활용한 Redisson Lock 처리

Spring AOP와 Redisson을 결합하여 어노테이션 기반 락 처리를 구현할 수 있습니다.

어노테이션 정의

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
    String lockName();
    long waitTime() default 10;
    long leaseTime() default 60;
}

AOP를 활용한 락 처리

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DistributedLockAspect {
    private final RedissonClient redissonClient;

    public DistributedLockAspect(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Around("@annotation(lockAnnotation)")
    public Object around(ProceedingJoinPoint joinPoint, DistributedLock lockAnnotation) throws Throwable {
        String lockName = lockAnnotation.lockName();
        long waitTime = lockAnnotation.waitTime();
        long leaseTime = lockAnnotation.leaseTime();

        RLock lock = redissonClient.getLock(lockName);
        if (lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS)) {
            try {
                return joinPoint.proceed();
            } finally {
                lock.unlock();
            }
        } else {
            throw new RuntimeException("Failed to acquire lock: " + lockName);
        }
    }
}

어노테이션 적용

import org.springframework.stereotype.Service;

@Service
public class SampleService {

    @DistributedLock(lockName = "sampleLock", waitTime = 5, leaseTime = 30)
    public void performCriticalTask() {
        System.out.println("Executing critical task with distributed lock.");
    }
}

 

 

Redisson Lock은 분산 환경에서 데이터 동기화를 관리하는 데 강력한 도구입니다.

클라이언트 공통화, 공통 유틸리티, 어노테이션 기반 처리 등을 활용해 생산성을 높이고 코드 품질을 개선할 수 있도록 작성된 예제를 참고하여 효율적으로 적용해 보세요.

 

#Redisson
#RedissonLock
#SpringBoot
#Redis
#분산락
#RedisLock
#Redisson예제
#SpringBootRedisson
#분산락처리
#Redis분산락
#Redisson활용
#Java개발
#SpringBoot개발
#레디슨락
#레디스락처리

반응형