Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Gridgain应用程序在1天的压力测试后开始失败_Java_Testing_Fileinputstream_Stress_Gridgain - Fatal编程技术网

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

Java Gridgain应用程序在1天的压力测试后开始失败,java,testing,fileinputstream,stress,gridgain,Java,Testing,Fileinputstream,Stress,Gridgain,所以我有一个在gridgain上运行的应用程序,在它开始变得有趣之前,它成功地进行了大约12-24小时的压力测试。在这段时间之后,应用程序将突然开始响应所有查询,异常为java.nio.channels.ClosedByInterruptException(完整堆栈跟踪位于 失败的方法是(编辑为使用@stephenc feedback) 并且调用函数正确地关闭对象 private void fillContactBuffer(final File signFile) { contactB

所以我有一个在gridgain上运行的应用程序,在它开始变得有趣之前,它成功地进行了大约12-24小时的压力测试。在这段时间之后,应用程序将突然开始响应所有查询,异常为java.nio.channels.ClosedByInterruptException(完整堆栈跟踪位于

失败的方法是(编辑为使用@stephenc feedback

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

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个这样的通道)。似乎过了一段时间它就无法打开文件了,我无法解释为什么会发生这种情况,如果有人能告诉我是什么原因导致了这种情况,我将非常感激。如果这可能与文件句柄耗尽有关,我希望能听到一些有关的提示确定查找…即在JVM运行时查询JVM,或使用linux命令行工具查找有关当前打开的句柄的更多信息

更新:我一直在使用命令行工具查询lsof的输出,但没有看到文件句柄处于打开状态的任何证据……网格中的每个节点都有一个非常稳定的打开文件配置文件,我可以看到随着上述代码的执行而发生变化……但它总是返回到一个稳定数量的open文件


与此问题相关:

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

  • 可能还有其他一些代码可以打开文件
  • 可能还有其他一些代码调用
    createChannel(…)
    而不调用
    fillContactBuffer(…)
  • 如果
    channel.position(0)
    抛出异常,则通道将不会关闭。修复方法是重新排列代码,使以下语句位于
    try
    块内

    channel.position(0);
    return new FileChannelImpl(channel);
    
  • 编辑:查看堆栈跟踪,似乎这两个方法在不同的代码库中。我将矛头指向
    createChannel
    方法。它可能存在泄漏,即使它不是问题的根源。它需要一个in internal
    finally
    子句,以确保在f例外

    类似这样的操作应该可以做到。请注意,您需要确保
    finally
    块在成功时不会关闭频道

    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调用通过抛出异常来响应中断,这里抛出的根异常看起来像这样的异常

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

    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 (...) {
                    ... 
                }
            }
        }
    }