贫瘠之地

华北无浪漫,死海扬起帆
多少个夜晚,独自望着天

0%

升级 MacOS 14 导致 embedded-redis 不兼容

背景

一直都没更新操作系统的版本,心血来潮更新了 MacOS 的 14(Sonoma)

macOS Sonoma - Apple (中国大陆)

然后发现单测竟然跑不通了,但是 push 上去的代码 CI 依然可以通过,所以当时基本就确定是版本升级带来的兼容性问题了

看了下日志,是嵌入的 Redis 运行不起来

1
2
3
4
5
java.lang.RuntimeException: Can't start redis server. Check logs for details. Redis process log: 

at redis.embedded.AbstractRedisInstance.awaitRedisServerReady(AbstractRedisInstance.java:70)
at redis.embedded.AbstractRedisInstance.start(AbstractRedisInstance.java:42)
at redis.embedded.RedisServer.start(RedisServer.java:9)

这里嵌入的 Redis 是用来 mock 单测内的 Redis 服务端的

使用的开源 kstyrc/embedded-redis: Redis embedded server for Java integration testing (github.com)

排查

检查端口占用

当然第一时间检查端口占用,这种代码内嵌的服务经常会出现关闭失败的情况,导致主线程已经结束了实际服务还在运行,导致端口占用;当然从异常栈信息来看并不是端口占用导致的

1
lsof -i :<端口号>

debug

异常信息上表示 Check logs for details

事实上也没有日志可以查看,只能 debug 进行查看了

具体位置在 org.apache.commons.io.IOUtils.AbstractRedisInstance.start()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public synchronized void start() throws EmbeddedRedisException {
if (active) {
throw new EmbeddedRedisException("This redis server instance is already running...");
}
try {
redisProcess = createRedisProcessBuilder().start();
logErrors();
// 这里在等待服务端返回的数据
awaitRedisServerReady();
active = true;
} catch (IOException e) {
throw new EmbeddedRedisException("Failed to start Redis instance", e);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void awaitRedisServerReady() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(redisProcess.getInputStream()));
try {
String outputLine;
do {
outputLine = reader.readLine();
// 这里为 null 所以抛出了异常
if (outputLine == null) {
//Something goes wrong. Stream is ended before server was activated.
throw new RuntimeException("Can't start redis server. Check logs for details.");
}
} while (!outputLine.matches(redisReadyPattern()));
} finally {
IOUtils.closeQuietly(reader);
}
}

但是 debug 也没发现哪里有日志

事实上还找到了一个 issue 来询问这个问题

"Can't start redis server. Check logs for details" - which logs???? · Issue #51 · kstyrc/embedded-redis (github.com)

看下方的评论很多人都是因为 Windows 的不兼容导致

对应的 issue

只能继续找 issue,看看有没有解决方案,还真找到了一样的问题

Unable to run on macOS Sonoma · Issue #135 · kstyrc/embedded-redis (github.com)

有老哥 fork 后解决了不兼容问题

codemonstur/embedded-redis: Redis embedded server (github.com)

解决

因为是本地单测环境问题,所以引用开源的风险也不大

其次因为之前的这个依赖在 parent 包内管理,很难快速进行版本升级

所以决定 fork 代码后修改坐标,在本地打一个相同坐标的包进行覆盖

1
2
3
4
5
<dependency>
<groupId>com.github.kstyrc</groupId>
<artifactId>embedded-redis</artifactId>
<version>0.6</version>
</dependency>

总结

真 · 跑起来就不要再动了

不要轻易更新版本 : (