windows版kafka出现java.nio.file.FileSystemException

摘要:

本博客是从工作中遇到的问题(windows版kafka 工作一段时间出现java.nio.file.FileSystemException,另一个程序正在使用此文件,进程无法访问)通过对问题的查询,寻找出该问题的原因并提出多种解决办法。本次采用打补丁的方式解决此问题,经过长时间的运行,验证此方法是可用的。

问题描述:

​ 之前的项目在linux上使用过kafka,功能非常好用,另一个设备应用场景也需要kafka,不同的是操作系统是windows版本,在windows部署后,在使用过程中经常崩掉。查看日志报错如下:

在这里插入图片描述

报错的内容是:java.nio.file.FileSystemException 另一个程序正在使用此文件,进程无法访问。

解决思路:

参考思路:https://stackoverflow.com/questions/59187659/windows-kafka-java-nio-file-filesystemexception

​ 经过查询该问题的原因是kafka日志清理在windows中重命名函数有问题,在linux一个程序打开文件,另一个程序重命名文件是没有问题的,但在windows中加了锁的机制,一个文件打开后,另一个程序重命名就会报错。这样导致kafka抛异常宕机。

解决的方法有:

1.手动启动

​ 手动删除kafka的日志文件,重启kafka 。

2.修改配置文件
log.retention.hours=-1
log.cleaner.enable=false

这样就不会触发kafka日志清理功能,但是这样会造成日志不断的增大。

3.在windows上搭建docker,然后安装zookeeper、kafka

这种方法是可以解决这个问题,但是这边的机器配置比较低,又增加些组件,显然不太适合,如果有资源够的情况下是可以用这个方法。

安装方法参考:https://blog.csdn.net/sayoko06/article/details/104020621

4.使用补丁

https://github.com/apache/kafka/pull/6329

https://github.com/apache/kafka/pull/6329/commits/3eceb9ea1d96d545d1c60713ea40e1ce7b354dce

补丁的内容:

diff --git a/clients/src/main/java/org/apache/kafka/common/record/FileRecords.java b/clients/src/main/java/org/apache/kafka/common/record/FileRecords.java
index 481bacfa3f..f81e62daeb 100644
--- a/clients/src/main/java/org/apache/kafka/common/record/FileRecords.java
+++ b/clients/src/main/java/org/apache/kafka/common/record/FileRecords.java
@@ -110,14 +110,7 @@ public class FileRecords extends AbstractRecords implements Closeable {
     public FileChannel channel() {
         if (OperatingSystem.IS_WINDOWS) {
             synchronized (mutex) {
-                if (channel == null) {
-                    try {
-                        channel = FileChannel.open(file.toPath(), StandardOpenOption.CREATE, StandardOpenOption.READ,
-                                StandardOpenOption.WRITE);
-                    } catch (IOException e) {
-                        throw new UncheckedIOException(e);
-                    }
-                }
+                reopenChannelIfClosed();
                 return channel;
             }
         } else {
@@ -187,8 +180,25 @@ public class FileRecords extends AbstractRecords implements Closeable {
      * Commit all written data to the physical disk
      */
     public void flush() throws IOException {
-        if (channel != null) {
-            channel.force(true);
+        if (OperatingSystem.IS_WINDOWS) {
+            synchronized (mutex) {
+                reopenChannelIfClosed();
+            }
+        } else {
+            if (channel != null) {
+                channel.force(true);
+            }
+        }
+    }
+
+    private void reopenChannelIfClosed() {
+        if (channel == null) {
+            try {
+                channel = FileChannel.open(file.toPath(), StandardOpenOption.CREATE, StandardOpenOption.READ,
+                        StandardOpenOption.WRITE);
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
         }
     }
 
diff --git a/core/src/main/scala/kafka/log/Log.scala b/core/src/main/scala/kafka/log/Log.scala
index 5ad3c3e581..41158fd76b 100644
--- a/core/src/main/scala/kafka/log/Log.scala
+++ b/core/src/main/scala/kafka/log/Log.scala
@@ -41,7 +41,7 @@ import org.apache.kafka.common.record.FileRecords.TimestampAndOffset
 import org.apache.kafka.common.record._
 import org.apache.kafka.common.requests.FetchResponse.AbortedTransaction
 import org.apache.kafka.common.requests.{EpochEndOffset, ListOffsetRequest}
-import org.apache.kafka.common.utils.{Time, Utils}
+import org.apache.kafka.common.utils.{OperatingSystem, Time, Utils}
 import org.apache.kafka.common.{KafkaException, TopicPartition}
 
 import scala.collection.JavaConverters._
@@ -758,6 +758,11 @@ class Log(@volatile var dir: File,
     lock synchronized {
       maybeHandleIOException(s"Error while renaming dir for $topicPartition in log dir ${dir.getParent}") {
         val renamedDir = new File(dir.getParent, name)
+
+        if (OperatingSystem.IS_WINDOWS) {
+          this.close()
+        }
+
         Utils.atomicMoveWithFallback(dir.toPath, renamedDir.toPath)
         if (renamedDir != dir) {
           dir = renamedDir

实现方法:

本次采用的是这个打过补丁的版本,进行重新编译

https://github.com/apache/kafka/tree/0baf9c158b5681a55df4de3a0e6193d32b1433ff

编译后的安装包:

链接:https://pan.baidu.com/s/18L2kCY2WXsKqqZoEDJSaLA
提取码:vaj2
此安装包已经我们多次验证,能够成功的解决这个问题。

参考:

https://hiddenpps.blog.csdn.net/article/details/80418297?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.not_use_machine_learn_pai&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.not_use_machine_learn_pai

https://blog.csdn.net/u013160932/article/details/79874709?utm_medium=distribute.pc_relevant.none-task-blog-searchFromBaidu-4.not_use_machine_learn_pai&depth_1-utm_source=distribute.pc_relevant.none-task-blog-searchFromBaidu-4.not_use_machine_learn_pai

https://blog.csdn.net/qq_40125653/article/details/111867706

ribute.pc_relevant.none-task-blog-searchFromBaidu-4.not_use_machine_learn_pai

https://blog.csdn.net/qq_40125653/article/details/111867706

https://www.bbsmax.com/A/ke5jPeW7zr/

当你遇到错误提示 `ERROR Exiting Kafka due to fatal exception (kafka.Kafka$)` 并伴随有 `java.nio.file.NoSuchFileException: --override` 时,通常表明在启动 Kafka 的过程中指定了一个不存在的文件路径或者参数解析出现了问题。以下是详细的分析和解决方案: --- ### **可能的原因及解决办法** 1. **错误地使用了 `--override` 参数** 在 Kafka 的启动脚本中,`--override` 是用于覆盖默认配置的一个选项,但它并不是用来指定文件路径的工具。如果你试图通过 `--override` 指向某个文件(如日志目录或其他资源),这种做法是不正确的。 正确的方式应该是编辑 Kafka 的主配置文件 `server.properties` 或者在命令行上单独传递合法的关键字-值对给它。例如: ```bash ./bin/kafka-server-start.sh config/server.properties \ --override log.dirs=/path/to/logs \ --override num.partitions=50 ``` 2. **缺少必要的配置文件或路径** 错误消息显示的是找不到某特定文件的问题 (`NoSuchFileException`) ,这说明你在命令里提供的路径指向了一个无效的目标地址。检查一下所提供的所有涉及物理存储位置的部分——尤其是那些自定义添加进去的新字段名与对应的值是否都正确无误。 3. **Kafka 配置加载机制冲突** 如果同时从多种来源引入配置数据(比如既引用外部 property 文件又叠加 inline override 规则集),那么有可能导致内部处理逻辑混乱进而抛出异常退出程序。尽量避免混合复杂度较高的组合方案除非必要,并且始终保证核心基础设定保持一致性和完整性。 4. **操作系统层面的因素** 对于某些敏感环境来说(如同一时刻允许多实例并发运行等场景),如果没有妥善隔离各自的作业空间就会引发竞争条件之类的状况最终反映到此类崩溃现象上来。因此还需要兼顾考虑宿主机的整体健康状态以及相关依赖库的状态等因素的影响程度有多大。 --- ### **推荐调试步骤** 1. 只保留最基本的配置来测试能否顺利启动服务端口监听等功能模块; ```bash ./bin/kafka-server-start.sh config/server.properties ``` 2. 增量式逐步加入额外定制化的改动内容直到重现故障为止; ```bash # 添加第一个扩展规则... ./bin/kafka-server-start.sh config/server.properties \ --override broker.id=2 # 继续堆叠更多修改项直至出现问题发生点明确下来 ``` 3. 查阅完整异常跟踪记录定位确切触发源头所在区域范围然后针对其特性做进一步深入探究优化调整策略制定相应预防措施保障未来不再重复出现类似隐患风险情况的发生概率降到最低限度之内即可满足需求目标达成共识完成任务结束本次交流讨论过程谢绝打扰祝好运常伴左右万事如意身体健康心情愉悦每一天过得充实快乐无比幸福美满家庭和睦万事顺遂一路平安吉祥如意鸿运当头紫气东来春风得意马蹄疾一日看尽长安花! --- **
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值