You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.1.8.RELEASE Kafka测试文件占用删除失败求助

解决Windows下Kafka测试时临时文件被占用无法删除的问题

我之前在Windows环境下做Kafka测试时也遇到过一模一样的问题,这个错误本质是Windows的文件锁机制导致Kafka临时目录的文件句柄没有及时释放,结合你的代码来看,主要是资源关闭的顺序和完整性有问题,下面是具体的解决方案:

问题根源分析

你的报错信息显示Kafka的临时日志文件被其他进程占用,无法删除:

[Thread-2] ERROR o.a.k.t.TestUtils - Error deleting C:\Users\usr\AppData\Local\Temp\kafka-255644115154741962
java.nio.file.FileSystemException: C:\Users\usr\AppData\Local\Temp\kafka-255644115154741962\version-2\log.1: The process cannot access the file because it is being used by another process.

查看你的测试代码,发现两个关键问题:

  1. 没有关闭ZkUtils实例,它内部持有和Kafka临时存储相关的资源,导致文件句柄无法释放
  2. 资源关闭顺序不合理,应该先关闭依赖组件,再关闭基础服务

修复方案

调整资源关闭的顺序,确保所有相关资源都被正确释放,同时针对Windows的特性增加短时间延迟,让系统有足够时间释放文件锁。修改后的代码如下:

import org.I0Itec.zkclient.ZkClient;
import org.junit.Test;
import kafka.utils.ZKStringSerializer$;
import kafka.utils.ZkUtils;
import kafka.zk.EmbeddedZookeeper;

public class BaseTest {
    private static final String ZKHOST = "127.0.0.1";

    @Test
    public void producerTest(){
        EmbeddedZookeeper zkServer = null;
        ZkClient zkClient = null;
        ZkUtils zkUtils = null;
        
        try {
            // 初始化Zookeeper服务和客户端
            zkServer = new EmbeddedZookeeper();
            String zkConnect = ZKHOST + ":" + zkServer.port();
            zkClient = new ZkClient(zkConnect, 30000, 30000, ZKStringSerializer$.MODULE$);
            zkUtils = ZkUtils.apply(zkClient, false);

            // 在这里编写你的测试逻辑
        } finally {
            // 按优先级关闭资源:先关闭ZkUtils,再关闭ZkClient,最后关闭Zookeeper服务
            if (zkUtils != null) {
                zkUtils.close();
            }
            if (zkClient != null) {
                zkClient.close();
            }
            if (zkServer != null) {
                zkServer.shutdown();
                // Windows下文件句柄释放存在延迟,增加500ms等待时间
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

额外优化(可选)

如果上述方案仍然无法解决问题,可以尝试手动删除临时目录,使用Apache Commons IO的FileUtils.deleteDirectory()方法,它会自动重试删除操作,避免单次删除失败:

  1. 先添加Commons IO依赖(Maven为例):
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
    <scope>test</scope>
</dependency>
  1. 在测试结束后手动删除临时目录:
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;

// ... 在shutdown和sleep之后添加:
File kafkaTempDir = new File(System.getProperty("java.io.tmpdir"), "kafka-*");
try {
    FileUtils.deleteDirectory(kafkaTempDir);
} catch (IOException e) {
    e.printStackTrace();
}

内容的提问来源于stack exchange,提问作者Wahid Gazzah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:50:17