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와 서버 간의 통신이 정상적으로 동작되는 것을 확인 할 수 있습니다!!