이렇게 레디스 서버가 다운됐다고 해보자.
그럴 때 레디스를 사용하는 요청이 서버로 오면
시간이 1분이나 걸렸다.
spring.data.redis.timeout=2000ms
spring.data.redis.connect-timeout=2000ms
이렇게 타임아웃 설정을 해줬는데도 그랬다.
로그를 보면 계속 재연결을 하느라 시간이 오래 걸리는 것으로 보였다.
그래서,
@Bean
public RedisConnectionFactory redisConnectionFactory() {
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.clientOptions(ClientOptions.builder()
.disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS) // 연결이 없으면 바로 명령어 거절
.autoReconnect(false) // 자동 재연결 비활성화
.cancelCommandsOnReconnectFailure(true) // 재연결 실패시 진행중인 명령어 취소
.build())
.commandTimeout(Duration.ofSeconds(2))
.build();
RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration("localhost", 6379);
return new LettuceConnectionFactory(serverConfig, clientConfig);
}
우선 자동연결 비활성화하고
재연결 실패 시 진행중인 명령어를 취소하도록 설정했다.
@Bean
public RedisConnectionFactory redisConnectionFactory() {
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.clientOptions(ClientOptions.builder()
.disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS) // 연결이 없으면 바로 명령어 거절// 자동 재연결 비활성화
.build())
.commandTimeout(Duration.ofSeconds(2))
.build();
RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration("localhost", 6379);
return new LettuceConnectionFactory(serverConfig, clientConfig);
}
설정 정보는 이렇게 바꿨다.
cancelCommandsOnReconnectFailure이건 인텔리제이에서 deprecated됐다고 알려줘서 뺐는데 잘 작동했다.
또 다른 문제가 있었다.
레디스에 재연결을 하지 않는 것...!
그래서, 레디스 재연결을 하도록 비활성화 부분을 제거해주었다.
그런데, 레디스에 문제가 있을 때 fallback은 하는데 서킷브레이커가 이 예외를 잡고서 count를 하지 않았다.
왜 그런건지는 이유를 알 수 없었고 계쏙
: Redis check failed, using DB fallback: Redis exception
이런 로그만 찍혔다(이건 내가 찍도록 설정한 로그다)
그래서, 로그가 더 자세하게 어떤 예외가 터지는지 나오도록 했다.
이런 예외가 발생했따...!
그래서, 이걸 서킷브레이커가 잡는 예외로 추가해주었다.
이제 정상적으로 레디스에서 문제가 발생하면 서킷브레이커가 이를 감지해서 체크하고, 서킷을 열거나 닫거나 작업한다.
그 정보는 디스코드 채널에 알림으로 보내도록 설정해두었다.