【问题标题】:Java app throws ClosedByInterruptException immediately when opening a socket, cause?Java 应用程序在打开套接字时立即抛出 ClosedByInterruptException,原因是什么?
【发布时间】:2011-11-17 03:39:45
【问题描述】:

我有一个 Java 应用程序,它可以打开许多到一个地址的连接,一次可能在 2,000 个左右,几乎没有任何活动,主要是为了监视目的而打开,不时传递几个字节。当需要打开新连接时,它会自动打开它们并将它们添加到其池中。但有时,由于未知原因,应用程序在创建到远程地址的套接字期间/之后立即收到 ClosedByInterruptException。据我所知,这仅在客户端由于线程中断信号而发生。我已经检查并重新检查了问题区域周围的源代码,看起来还可以。我希望我能获得某人的专业知识,以了解是否存在其他原因,例如,除了源代码之外,是否存在导致这种情况的系统原因?有硬件原因吗?服务器级别/路由器级别?我的网络知识我会认为是业余的,但是对于路由器来说,2K 连接是否太多了?

INFO  [08 Sep 2011 23:11:45,982]: Reconnecting id 20831
ERROR [08 Sep 2011 23:11:45,990]: IOException while creating plain socket channel
java.nio.channels.ClosedByInterruptException
    at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:184)
    at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:518)
    at com.*.createSocketChannelPlain(MyTask.java:441)
    at com.*._executeTask(MyTask.java:176)
    at com.*.executeTask(MyTask.java:90)
    at com.*.ThreadPool$WorkerThread.run(ThreadPool.java:55)
ERROR [08 Sep 2011 23:11:45,990]: Could not open socket
WARN  [08 Sep 2011 23:11:45,990]: WorkerThread_24 received interrupted exception in ThreadPool
java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at com.*.TaskQueue.getTask(TaskQueue.java:39)
    at com.*.ThreadPool$WorkerThread.run(ThreadPool.java:48)

更新:我想尽我所能帮助其他人为诊断做出贡献。所以这里是发生异常的实际函数,唯一的区别是我添加到第 441 行的行标记。

private SocketChannel createSocketChannelPlain() throws TaskFailedException {
    SocketChannel socketChannel = null;
    try {
        // Create a non-blocking socket channel to use to communicate for imap connection
        socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);
        try {socketChannel.socket().setSoLinger(true, 0);} catch (Exception e) {}
        try {socketChannel.socket().setKeepAlive(true);} catch (Exception e) {}
        /*Line 441*/ socketChannel.connect(new InetSocketAddress(_HOSTNAME, _PORT));
        //System.out.println("Started connection");

        // Complete connection
        while (!socketChannel.finishConnect()) {
            // do something until connect completed
            try {
                //do what you want to do before sleeping
                Thread.sleep(500);//sleep for 500 ms
                //do what you want to do after sleeping
            } catch(InterruptedException ie){
                //If this thread was interrupted by another thread 
                try { socketChannel.close(); } catch (Exception e) {}
                finally { socketChannel = null; }
                break;
            }
        }
        //System.out.println("Finished connecting");

        return socketChannel;
    } catch (IOException e) {
        logger.error("IOException while creating plain socket channel to gmail", e);
        try { socketChannel.close(); } catch (Exception e1) {}
        finally { socketChannel = null; }
        //throw new TaskFailedException("IOException occurred in createSocketChannel");
    }
    return socketChannel;
}

【问题讨论】:

    标签: java sockets exception interrupted-exception


    【解决方案1】:

    你在什么操作系统上运行它?我不了解 Windows,但在 Linux(可能还有其他类似 Unix 的操作系统)上,您可以通过拥有大量套接字来耗尽文件句柄。您可以通过在运行 Java 应用程序之前执行 ulimit -n 8192 或类似操作来解决此问题。或者,编辑/etc/security/limits.conf 并设置nofile。综上所述,ClosedByInterruptedException 会以一种奇怪的方式注意到这一点。

    如果上述不是问题,接下来我会尝试运行 tcpdump(如果我们谈论的是无 GUI 机器)或 Wireshark(如果我们不是)并捕获程序产生的流量,寻找连接开始时发生的奇怪事情。

    【讨论】:

    • 这是 linux,Debian。实际上我之前遇到了文件描述符问题,然后我经常收到的异常描述是“错误的主机名”。从那以后,我设置了启动脚本以大大提高限制。 tcpdumping 虽然实际上是一个我还没有尝试过的好主意。
    • 原来 sysadmin 没有让我 tcpdump 它...稍后将不得不在个人系统上尝试一下。
    • 或者,如果你给他命令,他可能会为你做? tcpdump -i any -s 0 -w /tmp/casey.pcap port 80 大概是对的,我猜?也许添加谷歌的网络和你的源 IP 作为限制,以避免倾销其他人的流量......
    • @casey,你有没有得到这个?如果你得到一个,我会对结果感兴趣。我从未有过这种特殊的效果,但我们操作的一些系统做类似的事情......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多