본문 바로가기
Java

[Spring Boot] Redis Pub/Sub 설정 및 사용법!!

by parkjp 2023. 8. 9.

 

안녕하세요.

오늘은 간단하게 Spring Boot에서 Redis Pub/Sub 설정하는 법을 알아보도록 하겠습니다~!

 

 

1. Dependency 설정하기

 

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis'
}

 

 

 

2. Configuration 설정하기

 

 

// @Configuration Class

@Bean
public RedisConnectionFactory redisConnectionFactory() {
    RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
    redisStandaloneConfiguration.setHostName(host);
    redisStandaloneConfiguration.setPort(port);
    // redisStandaloneConfiguration.setPassword(RedisPassword.of(password));

    return new LettuceConnectionFactory(redisStandaloneConfiguration);
}

// Pub/Sub ListenerContainer
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(@Autowired RedisConnectionFactory factory) {
    RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    container.setConnectionFactory(factory);

    return container;
}

// redistemplate bean은 각자에 맞춰서 설정.
@Bean
public RedisTemplate<String, Content> redisTemplate(@Autowired RedisConnectionFactory factory) {
    RedisTemplate<String, Content> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(factory);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Content>(Content.class));

    return redisTemplate;
}

 

 

자 여기까지 하셨으면 심플하게 Pub/Sub을 쓸 준비가 완료되었습니다.

자 그럼 예시로 어떻게 쓰는지 알아보겠습니다.

 

 

3. Redis Pub/Sub 사용법

 

// Service Class

@Service
@RequiredArgsConstructor
public class TestService {

    private final RedisMessageListenerContainer container;
    private final Publisher redisPublisher;
    private final Subscriber redisSubscriber;
    
    private final ChannelTopics topics; // 토픽들을 저장하는 저장소 클래스
    
    public void subscribe(String roomId) {
        // 토픽 생성
        ChannelTopic topic = new ChannelTopic(roomId);
        
        // 이 인스턴스(서버)의 Subscriber가 해당 토픽으로 들어온 메세지를 Listen하도록 설정.
        container.addMessageListener(redisSubscriber, topic);
        
        // 추후 해당 토픽을 구독해지 하기 위해 저장.
        topics.put(topic.getTopic(), topic);
    }
    
    public void publish(String roomId, Content content) {
        redisPublisher.publish(roomId, content);
    }
}


// Publisher Class

@Component
@RequiredArgsConstructor
public class Publisher {

    private final RedisTemplate<String, Content> redis;

    public void publish(String roomId, Content content) {
        redis.convertAndSend(roomId, content);
    }
}

// Subscriber Class

@Service
@RequiredArgsConstructor
public class Subscriber implements MessageListener {

    private final ChannelTopics topics;
    private final RedisMessageListenerContainer container;
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public void onMessage(Message message, byte[] pattern) {
        try {
            Content content = objectMapper.readValue(message.getBody(), Content.class);
			
            // 메세지 받았을 때 처리
            
            // 만약 메세지를 받고 구독해지를 원할 경우.
            String topicName = new String(message.getChannel());
            ChannelTopic topic = topics.get(topicName);
            container.removeMessageListener(this, topic);
            topics.remove(topicName);

        } catch (IOException e) {
            // exception 처리
        } 
    }
}

@Repository
public class ChannelTopics extends ConcurrentHashMap<String, ChannelTopic> {

}

 

 

보통 Pub/Sub은 다중 인스턴스를 고려하여 많이들 쓰는데요.

간단하게 예시를 들어서 알아보았습니다.

 

 

 

 

 

 

 

반응형