java.nio.channels.Selector#openはループバックアドレス間の通信(ESTABLISH)を発生させる(Windows)

はじめに

業務でJavaアプリを扱っていて、ループバックアドレス間のESTABLISHが大量に発生してEphemeralポートを食いつぶしてしまうという事象に遭遇しました。

その際の調査録です。以下の内容はWindowsでの話(Linuxでは発生しない)です。

疑わしいアプリがいろいろ…

まず自分の開発マシンで再現検証するにあたり、
何がループバックアドレス間のESTABLISHを発生させているかをnetstat -anbで確認したところ…

  • Intelij IDEA (Java製)
  • Tomcat (Java製)
  • メールクライアント
  • …etc

容疑者がたくさんいました… orz

このあたりのアプリの共通点考えると、Socket使う系?が原因で起きてるのかなという感じです。
とりあえずこれらをすべて停止し、問題の業務Javaアプリと向き合います。

業務Javaアプリの調査

扱っていた業務Javaアプリですが、以下機能がありSocketを使いまくるアプリでした。

  • TCPサーバ
  • UDPサーバ
  • SNMPサーバ
  • Mailクライアント

これらの機能一つ一つ切り分けていくと、java.nio.channels.Selector使ってる機能だけがループバックアドレス間のESTABLISHを発生させているということがわかりました。

ループバックアドレス間のESTABLISHを発生させる最小コード

これだけでループバックアドレス間のESTABLISHが発生します。

import java.nio.channels.Selector;

public class Main {
    public static void main(String[] args) throws Exception {
        Selector selector = Selector.open();
        Thread.sleep(100000);
    }
}

Selctorの実装みた感じだと最終的にはSocketオープンするようなとこにたどり着くようです。またオープンしたselectorはちゃんとクローズすれば、ループバックアドレス間の通信も閉じます。

というわけで

業務Javaアプリでループバックアドレス間のESTABLISHが大量に発生させていた原因は、

オープンしたselectorのクローズ漏れの累積

で、一見落着でした。めでたしめでたし。

再現環境情報

以下の環境で発生を確認しました。

  • Windows10/Windows2012R2
  • Java6/7/8(u111)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA