본문 바로가기

개발중/Spring Boot & Redis

Spring Boot 기반 Redis Pub/Sub 구현: 분산 환경에서 Pod 간 이벤트 처리

728x90
반응형

목적

오늘은 Spring Boot 기반 프로젝트에서 Redis Pub/Sub을 설정하는 코드를 구현하려고 한다.

 

환경

분산 처리 환경(API들이 Pod로 분산 처리됨)에서 Redis를 Session Storage로 사용한다.

 

목표

특정 Pod에서 이벤트가 발생하면, Redis Pub/Sub을 통해 모든 Pod에 이벤트를 전달하는 구조를 구현한다.

 

구현

채널 구독

Redis Config 파일에 RedisMessageListenerContainer 를 Bean 등록해서 아래와 같이 PatternTopic 으로 채널을 구독한다.

여기서 채널을 구독하지 않으면 메세지를 수신할 수 없으니 유의하자.

 

@Bean
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory,
                                                    MessageListenerAdapter listenerAdapter) {
    RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.addMessageListener(listenerAdapter, new PatternTopic("SOOBIN_CHANNEL"));
    return container;
}

 

 

참고로 단일 또는 다중 채널을 구독할 수 있다.

new PatternTopic("SOOBIN_CHANNEL*")  > SOOBIN_CHANNEL 으로 시작하는 채널을 모두 구독한다.

new PatternTopic("SOOBIN_CHANNEL") > SOOBIN_CHANNEL 과 일치하는 채널을 모두 구독한다.

 

메세지 발신

"SOOBIN_CHANNEL" 채널에 메세지를 발행한다.

 

private final RedisTemplate<String, Object> redisTemplate;

public void publishToChannel(Object message) {
    redisTemplate.convertAndSend("SOOBIN_CHANNEL", message);
}

 

 

메세지 수신

"SOOBIN_CHANNEL" 채널을 구독하고 메세지를 수신한다.

 

MessageListener 를 상속 받아서 메세지를 수신하는 RedisMessageSubscriber.onMessage 를 구현한다.

CANNEL_PREFIX 와 일치하는 채널에서 메세지가 수신되면 RedisMessageSubscriber.onMessage 에서 메세지를 받을 수 있다.

 

MessageListener의 주된 역활은 아래와 같다.
- 메세지 구독메세지 브로커에서 발행된 메세지를 구독한다.
- 메세지 처리수신된 메세지에 대한 로직을 수행한다.
- 비동기 처리메세지를 비동기적으로 처리하므로 수신자는 메세지가 들어올 때까지 대기 상태에 있지 않는다.

 

@Service
@RequiredArgsConstructor
public class RedisMessageSubscriber implements MessageListener {

    private final static String CHANNEL_PREFIX = "SOOBIN_CHANNEL";

    /**
     * 메세지가 발행되면 이벤트를 받는 역활
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {

        // 채널
        String channel = new String(message.getChannel());

        // 메세지 내용
        String messageContent = new String(message.getBody());

    }
}

 

 

MessageListener 를 상속받은 RedisMessageSubscriber 을 Redis Confing Class 에 MessageListenerAdpter 를 Bean 으로 등록해야한다.

 

@Bean
public MessageListenerAdapter messageListener(RedisMessageSubscriber subscriber) {
    return new MessageListenerAdapter(subscriber);
}

 

728x90
반응형