
당장 오늘 있었던 트러블 슈팅이다. 이걸 5시간을 붙잡고 있던게 너무 웃겨(?)서 집 오자마자 글로 남겨본다. 결론은 너무나도 어이 없으니 해결 과정에 주목하여 읽어주면 감사하겠다!
별도의 도커 컨테이너로 띄워둔 back springboot WAS, redis 컨테이너를 도커 파일 & 도커 컴포즈로 함께 관리하도록 docker-compose.yml 파일을 만들며 테스트 중이었다. 그런데 잘 동작하던 springboot가 터지는 것 아닌가.
에러 로그를 보니 아래와 같았다.
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost/<unresolved>:6379
...
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:6379
Caused by: java.net.ConnectException: Connection refused: no further information
...?
localhost/:6379 라니 이게 뭔가 ㅠㅠ
lettuce, netty 모두 연결에 실패하는 것으로 보이는데 로컬에서는 잘 테스트가 되었는데 왜 그럴까. 트러블슈팅 해보자!
docker-compose.yml command 추가 (유효)
spring:
data:
redis:
host: localhost
port: 6379
password: mypassword
기존에 컨테이너에서 관리할 때와 로컬에서 관리할 때는 비밀번호를 redis 내부에서 설정해주었는데, 이제는 docker-compose로 관리할 것임으로 컨테이너가 사라지고 생성되어도 비밀번호를 계속 걸어주어야 했다.
그런데 docker-compose.yml 파일에 redis를 띄울 때 비밀번호를 설정해지 않아서 연결이 안되는 것이라고 생각했다. 실제로도 비밀번호가 틀리면 연결이 거부당해서 Connection refused가 발생할 수 있다.
command 사용하여 redis-server --requirepass mypassword --port 6379 로 비밀번호를 지정해주었다.
redis:
container_name: redis
networks:
- mynetwork
image: redis
restart: always
command: redis-server --requirepass mypassword --port 6379
ports:
- "6379:6379"
application.yml host 변경 (유효)
기존에는 local에서 redis를 올려두고 테스트하여 application.yml에 localhost로 되어있었는데, docker에서는 네트워크로 관리되어 컨테이너 host 명으로 ip가 매핑되어 구분되어있다.
실제로 매핑된 IP는 docker network inspect [네트워크 명] 으로 확인할 수 있다.
spring:
data:
redis:
host: redis
port: 6379
password: mypassword
application.yml password ' ' 추가 (효과 없음)
spring:
data:
redis:
host: redis
port: 6379
password: 'mypassword'
docker-compose.yml hostname 추가 (효과 없음)
redis:
container_name: redis
hostname: redis
networks:
- mynetwork
image: redis
restart: always
command: redis-server --requirepass mypassword --port 6379
ports:
- "6379:6379"
application.yml ssl secure 추가 (효과 없었음)
springboot 3.1 버전으로 올라가면서 lettuce를 쓰게 되어 ssl 설정을 해줘야 한다는 글도 보아 추가해보았지만 여전히 변하는 것은 없었다
실제로 이 방법이 효과가 있었다고 하니 (버전을 2.X 에서 3.X로 옮겨지면서) 문제가 생겼다면 이 방법도 확인해볼것
spring:
data:
redis:
host: redis
port: 6379
password: mypassword
ssl:
enabled: true
application.yml host 실제 ip로 지정 (효과 없었음)
몇시간 쯔음 되었을 때 뭔가 이상함을 느꼈다. 백 팀원은 내 레디스에 잘 접근해서 pub/sub 테스트를 하고 있었던 것이다..!
설마 설마 host 명인 redis를 인식 못하는건가? network 는 확인했는데..?! 하면서 host를 실제 도메인 명으로 바꿔보았다.
비록 비효율적이지만 로컬에서 서버에 있는 레디스로 테스트할 때 처럼 실제 도메인 명을 사용했는데도 안됐다.
spring:
data:
redis:
host: [실제 도메인명]
port: 6379
password: mypassword
어이없게도 원인은 자바 소스코드
원인은.. git 소스 코드 자체에서 redis Connection Factory 자체가 주석쳐있어서 host를 지정하지 못한 것이었다.
따라서 localhost로 계속 연결되었던 것이었다..
백 담당이 로컬에서 서버에 올라간 redis 통신을 하고 있어서 전혀 의심하지 못했는데 알고보니 혼자서 주석 해제하고 테스트하고 있었던거였다..
아..ㅋㅋㅋㅋㅋㅋㅋㅋ 그래도 어찌저찌 찾긴함..!
@Configuration
@RequiredArgsConstructor
public class RedisConfig {
private final RedisMessageListener redisMessageListener;
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
@Value("${spring.data.redis.password}")
private String password;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
// configuration.setHostName(host);
// configuration.setPort(port);
// configuration.setPassword(password);
return new LettuceConnectionFactory(configuration);
}
//..
}
이 글을 읽고 있다면 너무 허무하겠지만 정말 별 것 아닌 데에서 에러가 터짐을 오늘도 몸소 겪어버렸다. 인프라쪽에 내가 모르는게 있겠지 라는 생각에 잘 아는 springboot 쪽을 오히려 생각 안해버린.. 물론 통신 테스트를 잘 하고 있었기에 소스코드 문제일거라고는 생각도 못했다 ㅠㅠ 오늘도 뻘짓과 함께 성장한(?) 하루였다 ㅎㅅㅎ
https://github.com/spring-projects/spring-boot/issues/35612