기초적인 Consumer group 생성 문제 해결법

김형준·2025년 3월 6일
0

개요

grafana로 성능 테스트를 수행하기 위해 기존 로컬에 설치되어 있던 Redis 등의 의존성을 Docker로 변경하였다.

하지만 의존성을 수정하니 아래와 같은 문제들이 발생했다.

문제 상황 및 해결과정

Redis Cloud에서는 자체적으로 stream 키를 포함한 여러 데이터들을 미리 준비해 놓는다.

반면 Docker 상의 Redis에는 그런 게 없었기에 위와 같은 에러가 발생하게 된 것이다.

따라서 Docker의 Redis에 Stream이 없을 경우 생성되도록 MKCREATE 옵션을 사용하는 streamCommands()를 도입하였다.

public void afterPropertiesSet() {

    String streamKey = topic.getTopic();

    try {
        redisTemplate.execute((RedisCallback<Boolean>) connection -> {
        // 스트림 키, 그룹 이름, 시작 offset을 바이트 배열로 변환합니다.
            byte[] keyBytes = streamKey.getBytes(StandardCharsets.UTF_8);
            ReadOffset offsetBytes = ReadOffset.from("0");

            // streamCommands()를 통해 group 생성을 수행합니다.
            return Boolean.valueOf(
                    connection.streamCommands().xGroupCreate(keyBytes, GROUP_NAME, offsetBytes, true));
        });
    } catch (RedisBusyException e) {
        // 이미 그룹이 존재하는 경우 Redis는 "BUSYGROUP" 메시지를 포함한 에러를 반환하므로 이를 무시합니다.
        if (!e.getMessage().contains("BUSYGROUP")) {
            throw e;
        }
    }
        
        
    ...
}

하지만 이미 Consumer group이 존재하는 경우 RedisBusyException을 catch해도 예외로 인해 Spring의 정상적인 실행이 불가능했다.

Caused by: org.springframework.data.redis.RedisSystemException: Error in execution
at …

Caused by: io.lettuce.core.RedisBusyException: BUSYGROUP Consumer Group name already exists
at …

에러 메시지를 확인해보니 RedisBusyException을 cause로 갖는 RedisSystemException이 던져지고 있었다.

따라서 이를 잡을 수 있도록 catch문을 아래와 같이 수정했다.

try {
		...
} catch (RedisSystemException e) {
		if (e.getCause() == null || !e.getCause().getMessage().contains("BUSYGROUP")) { throw e; }
}

0개의 댓글

관련 채용 정보