오류 메세지
Caused by: java.lang.RuntimeException: Can't start redis server. Check logs for details.
at redis.embedded.AbstractRedisInstance.awaitRedisServerReady(AbstractRedisInstance.java:62)
at redis.embedded.AbstractRedisInstance.start(AbstractRedisInstance.java:39)
at redis.embedded.RedisServer.start(RedisServer.java:9)
at org.hoongoin.interviewbank.config.TestRedisConfig.startRedis(TestRedisConfig.java:19)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157)
... 104 common frames omitted
문제 상황
세부 설정이 다른 @SpringBootTest(classes={TestRedisConfig.class})
실행시, Failed to load ApplicationContext, Can't start redis server. 에러가 터졌다.
테스트 전체 실행시 authentication 테스트가 Fail하고 클래스 단독 실행시에는 성공.
@TestConfiguration
public class TestRedisConfig {
private RedisServer redisServer;
@Value("${spring.redis.port}")
private int port;
@PostConstruct
public void startRedis() {
redisServer = new RedisServer(port);
redisServer.start();
}
@PreDestroy
public void stopRedis() {
redisServer.stop();
}
}
Spring 애플리케이션에서 Redis를 사용하고 있어, testImplementation 'it.ozimov:embedded-redis:0.7.2'
를 사용해 SpringBootTest에서 임베디드 레디스를 사용하도록 만들었다.
원인
애플리케이션컨텍스트의 캐싱때문에, 클래스의 테스트가 끝날 때 마다 애플리케이션컨텍스트가 소멸되는 것이 아니다.
애플리케이션 컨텍스트가 소멸되지 않았는데, 새로운 애플리케이션 컨텍스트가 생성되면서, 레디스서버가 하나 더 생겼다. 레디스 서버가 이미 열려있는데, 동일한 포트로 또 레디스 서버를 열려다보니 이런 에러가 생겼다.
설정이 같은 애너테이션에 대해 스프링은 애플리케이션컨텍스트의 캐싱을 한다.
해결
- RuntimeException이 일어났을 때, 이미 레디스가 열려있다고 생각하고 넘어가준다.
- 다른 익셉션이 터졌을 때도 동일하게 해결하여, 레디스서버가 만들어지지 않을 수 있다.
@PostConstruct
public void startRedis() {
try {
redisServer = new RedisServer(port);
redisServer.start();
} catch (Exception e) {
}
}
- 포트를 Random하게 만들어, 레디스 서버를 만들어준다. 그러면 새로운 애플리케이션을 시작할 때 마다 새로운 레디스 서버가 생긴다.
- 단점: 레디스 서버가 여러개 켜질 수 있다. 메모리를 많이 잡아먹는다.
1번을 통해 문제를 해결해줬다.
'Backend > Spring' 카테고리의 다른 글
같은 클래스 내에서 메소드 호출 시 AOP 적용 문제 (0) | 2023.05.09 |
---|---|
@Transactional 전파 전략 (0) | 2023.05.07 |
DI와 IoC (0) | 2023.04.07 |
Spring Container와 Bean의 Lifecycle (0) | 2023.04.07 |
Spring Boot Controller Test (0) | 2023.04.07 |