gpt4 book ai didi

Java Gridgain 应用程序在压力测试 1 天后开始失败

转载 作者:行者123 更新时间:2023-11-28 20:34:25 25 4
gpt4 key购买 nike

所以我有一个在 gridgain 之上运行的应用程序,并且在它开始表现得很滑稽之前进行了大约 12-24 小时的压力测试,并且非常成功。这段时间过后,应用程序将突然开始回复所有异常 java.nio.channels.ClosedByInterruptException 的查询(完整堆栈跟踪位于 http://pastie.org/664717

失败的方法是(编辑为使用@stephenc 反馈)

public static com.vlc.edge.FileChannel createChannel(final File file) {
FileChannel channel = null;
try {
channel = new FileInputStream(file).getChannel();
channel.position(0);
final com.vlc.edge.FileChannel fileChannel = new FileChannelImpl(channel);
channel = null;
return fileChannel;
} catch (FileNotFoundException e) {
throw new VlcRuntimeException("Failed to open file: " + file, e);
} catch (IOException e) {
throw new VlcRuntimeException(e);
} finally {
if (channel != null) {
try {
channel.close();
} catch (IOException e){
// noop
LOGGER.error("There was a problem closing the file: " + file);
}
}
}
}

并且调用函数正确地关闭了对象

private void fillContactBuffer(final File signFile) {
contactBuffer = ByteBuffer.allocate((int) signFile.length());
final FileChannel channel = FileUtils.createChannel(signFile);
try {
channel.read(contactBuffer);
} finally {
channel.close();
}
contactBuffer.rewind();
}

该应用程序基本上用作分布式文件解析器,因此它执行大量此类操作(通常每个节点的每个查询会打开大约 10 个此类 channel )。似乎在一段时间后它无法打开文件,我无法解释为什么会发生这种情况,如果有人能告诉我可能导致这种情况的原因以及我如何进行跟踪,我将不胜感激它下来并修复它。如果它可能与文件句柄耗尽有关,我很想听听任何确定确定的提示......即在运行时查询 JVM 或使用 linux 命令行工具来查找有关当前打开的句柄的更多信息.

更新:我一直在使用命令行工具来查询 lsof 的输出,但未能看到文件句柄保持打开状态的任何证据......网格具有非常稳定的打开文件配置文件,我可以看到随着上述代码的执行而发生变化......但它总是返回到稳定数量的打开文件。

与此问题相关:Freeing java file handles

最佳答案

有几种情况可能无法关闭文件句柄:

  1. 可能还有一些其他代码可以打开文件。
  2. 可能还有其他一些代码调用了 createChannel(...) 而没有调用 fillContactBuffer(...)
  3. 如果channel.position(0) 抛出异常, channel 不会关闭。解决方法是重新排列代码,使以下语句位于 try block 内。

    channel.position(0);
    return new FileChannelImpl(channel);

编辑:查看堆栈跟踪,这两种方法似乎在不同的代码库中。我会将责任归咎于 createChannel 方法。它可能会泄漏,即使它不是问题的根源。它需要一个内部 finally 子句来确保在发生异常时关闭 channel 。

像这样的东西应该可以解决问题。请注意,您需要确保 finally block 不会在成功时关闭 channel !

public static com.vlc.edge.FileChannel createChannel(final File file) {
final FileChannel channel = null;
try {
channel = new FileInputStream(file).getChannel();
channel.position(0);
FileChannel res = new FileChannelImpl(channel);
channel = null;
return res;
} catch (FileNotFoundException e) {
throw new VlcRuntimeException("Failed to open file: " + file, e);
} catch (IOException e) {
throw new VlcRuntimeException(e);
} finally {
if (channel != null) {
try {
channel.close();
} catch (...) {
...
}
}
}
}

跟进很久以后

鉴于文件句柄泄漏已被排除在外,我的下一个理论是服务器端实际上是在使用 Thread.interrupt() 中断它自己的线程。一些低级 I/O 调用通过抛出异常来响应中断,这里抛出的根异常看起来就像这样一个异常。

这并不能解释为什么会发生这种情况,但我粗略地猜测,这是服务器端框架试图解决过载或死锁问题。

关于Java Gridgain 应用程序在压力测试 1 天后开始失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1605522/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com