Blog

[Spring][258] AWS EC2 Redis 분산락 구현

Category
Author
Tags
PinOnMain
1 more property

Redis 분산락 구현 ( AWS Server )

설치 환경

AWS EC2 Ubuntu
c5.xlarge

Redis EC2에 설치

sudo apt install lsb-release curl gpg curl -fsSL <https://packages.redis.io/gpg> | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] <https://packages.redis.io/deb> $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list sudo apt-get update sudo apt-get install redis
Shell
복사

Redis 설정 파일 변경

bind 127.0.0.1 -::1을 주석 처리하여 외부 접속 허용합니다.
protected-mode를 'yes'에서 'no'로 변경하여 보호 모드 비활성화합니다.

Redis 서버 재시작

sudo systemctl stop redis-server.service sudo systemctl start redis-server.service
Shell
복사
설정 변경 후 Redis 서버 재시작합니다.

Redis 서버 정상 작동 확인

sudo systemctl status redis-server.service
Shell
복사
Redis 서버가 정상적으로 작동하는지 확인합니다.

Redis 분산락 구현 ( Client )

Client 설정 ( application.properties )

# Redis spring.redis.host = x.x.x.x spring.redis.port = 6379
Plain Text
복사

Client 설정 ( RedissonConfig )

@Configuration public class RedissonConfig { @Value("${spring.redis.host}") private String redisHost; @Value("${spring.redis.port}") private int redisPort; private static final String REDISSON_HOST_PREFIX = "redis://"; @Bean public RedissonClient redissonClient() { RedissonClient redisson = null; Config config = new Config(); config.useSingleServer().setAddress(REDISSON_HOST_PREFIX + redisHost + ":" + redisPort); redisson = Redisson.create(config); return redisson; } }
Java
복사

Client 설정 ( KafkaConsumerService )

@Service @RequiredArgsConstructor @Slf4j public class KafkaConsumerService { private final UserService userService; private final KafkaProducerService producer; private final BookApplyDonationService bookApplyDonationService; private final RedissonClient redissonClient; @KafkaListener(topics = "user-event-apply-input-topic", groupId = "user-event-apply-consumer-group${GROUP_ID}", containerFactory = "kafkaListenerContainerFactory2") public void AdminUserEventApplyConsume2(String message) throws JsonProcessingException { // System.out.println("Received Message in group 'test-consumer-group2': " + message); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); UserEventApplyKafkaDto kafkaDto = objectMapper.readValue(message, UserEventApplyKafkaDto.class); RLock lock = redissonClient.getLock(String.valueOf(kafkaDto.getBookApplyDonationRequestDto().getBookId())); MessageKafkaDto messageKafkaDto = new MessageKafkaDto(); try { if (!lock.tryLock(3, 3, TimeUnit.SECONDS)) { // log.info("락 획득 실패"); throw new IllegalArgumentException("락 획득 실패"); } // log.info("락 획득 성공"); messageKafkaDto =new MessageKafkaDto(bookApplyDonationService.createBookApplyDonationKafka(kafkaDto.getBookApplyDonationRequestDto(), kafkaDto.getUserId()), kafkaDto.getCorrelationId()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); e.printStackTrace(); } finally { // log.info("finally문 실행"); if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) { lock.unlock(); // log.info("언락 실행"); } } String jsonString = objectMapper.writeValueAsString(messageKafkaDto); producer.sendMessage("user-event-apply-output-topic", jsonString); } }
Java
복사

Redis 정상 동작 확인

Redis와 서버 간의 통신이 정상적으로 동작되는 것을 확인 할 수 있습니다!!