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; }
}