문제 상황
평소처럼 로컬에서 테스트를 돌리는데 갑자기 수많은 테스트가 깨졌다. Embedded Redis 관련된 문제였는데, 예외 메시지가 단순히 Can't start redis server. Check logs for details 여서 처음엔 뭐가 문제인지 가늠할 수 없었다. (자세한 내용은 로그를 확인하라는데 로그를 제대로 찍어줘야 보죠..)
그래서 embedded redis 코드를 까보기 시작했는데 버전이 업데이트 되면서 MAC_OS_X 도 지원하는 모습을 확인할 수 있었다. 나는 M2 환경에서 테스트를 수행한 것이기 때문에 크게 문제가 되지 않을 것이라고 생각했다.
그래서 embedded redis 코드에 대해 열심히 디버깅 해본결과..
다음과 같이 arch에 x86_64가 바인딩되는 모습을 확인할 수 있었다.
근데 나는 분명 ARM 계열의 CPU 이기 때문에 뭔가 잘못되었다고 생각했다.
최근에 macOS를 14 버전인 Sonoma로 업데이트 했는데 이전에 잘 수행되던 테스트가 OS 업데이트를 기점으로 깨진 것을 미루어 보아 OS 업데이트로 인해 생긴 문제라는 가설을 세우게 되었다.
해결 방법
해결 방법은 간단하다. Redis 코드를 받고, Redis를 띄우고 Redis-server 바이너리 파일을 프로젝트에 추가하여 현재 OS에서 동작하도록 하면 된다.
// Redis 소스 다운로드
wget https://download.redis.io/releases/redis-6.2.8.tar.gz
tar -xvf redis-6.2.8.tar.gz
cd redis-6.2.8
// Redis 소스 컴파일 및 실행 파일 생성
make
// redis-server 실행
src/redis-server
다음과 같이 Redis server가 실행된다. 6379 포트가 사용중이라면 띄울 수 없으니 포트를 비워주자
앞서 실행했던 redis-server 바이너리 파일을 프로젝트에 추가한다.
Embedded Redis 설정 파일을 다음과 같이 작성한다.
/*
* Test 용 EmbeddedRedis / profile 이 local, default 일때만 활성화
* */
@Slf4j
@Profile({"local", "default"})
@Configuration
public class EmbeddedRedisConfig {
@Value("${spring.data.redis.port}")
private int redisPort;
private RedisServer redisServer;
@PostConstruct
public void redisServer() throws IOException {
// Application Context 가 2번 이상 실행될 때 포트 충돌 문제 해결
int port = isRedisRunning() ? findAvailablePort() : redisPort;
// MAC OS면 redis-server 바이너리 파일을 기반으로 실행
if (isMac()) {
redisServer = new RedisServer(Objects.requireNonNull(getRedisFileForArcMac()),
port);
} else {
redisServer = new RedisServer(port);
}
redisServer.start();
}
@PreDestroy
public void stopRedis() {
if (redisServer != null) {
redisServer.stop();
}
}
// 시스템 OS 확인
private boolean isMac() {
return Objects.equals(Objects.equals(System.getProperty("os.name"), "Mac OS X");
}
// redis-server 바이너리 파일을 가져온다
private File getRedisFileForArcMac() {
try {
return new ClassPathResource("binary/redis/redis-server").getFile();
} catch (Exception e) {
throw new EmbeddedRedisException("fail to get redis-server binary file");
}
}
...
}
결과적으로 앞서 했던 설정을 통해 Embedded Redis 관련 문제를 해결할 수 있었다. Embedded Redis는 참 좋은 라이브러리이지만 이것때문에 삽질한 걸 생각하면.. 아무튼 문제 없이 해결해서 다행이다