2

私は、おそらく一度に2,000の球場で、アドレスへの多くの接続を開いたままにしているJavaアプリを持っています。アクティビティはほとんどなく、時々数バイトを渡す監視目的でほとんど開いています。新しい接続を開く必要がある場合、自動的にそれらを開き、プールに追加します。ただし、理由は不明ですが、リモート アドレスへのソケットの作成中または作成直後に、アプリケーションが 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;
}
4

1 に答える 1

0

これを実行しているOSは何ですか?Windowsについてはわかりませんが、Linux(およびおそらく他のUnixライクなOS)では、多数のソケットを使用することでファイルハンドルが不足する可能性があります。ulimit -n 8192Javaアプリを実行する前に、または同様の方法でこれを回避できます。または、を編集/etc/security/limits.confして設定しnofileます。そうは言っても、ClosedByInterruptedExceptionこれに気付くのは奇妙な方法でしょう。

上記が問題でない場合、次に試してみるのは、実行tcpdump(GUIのない​​マシンについて話している場合)またはWireshark(そうでない場合)を実行して、プログラムが生成するトラフィックをキャプチャすることです。接続が開始されたときに発生している奇妙なことを探します。

于 2011-09-14T21:07:13.007 に答える