2

一定の非アクティブ状態の後にファイアウォールが接続をドロップするため、既存の商用 Java アプリケーションで SO_KEEPALIVE をアクティブにする必要があります。私はソース コードを所有していないので、変更できません (ソースがあれば、 socket.setKeepAlive(true) を追加するだけでかなり簡単になります)。だから私はいくつかの選択肢を探していました:

  • 最初に libkeepalive.so ( http://libkeepalive.sourceforge.net/ ) で作業しようとしました。これを LD_PRELOAD に入れると、telnet や nc などで機能するようですが、jrockit jvm で使用すると、この LD_PRELOAD は完全に無視され、SO_KEEPALIVE なしですべてのソケット オブジェクトがまだ作成されている

  • 次に、すべての TCP 接続に対してデフォルトでこの SO_KEEPALIVE をアクティブにするオプションがあるかどうか、OS レベルで検索しようとしました。残念ながら、redhat 6 エンタープライズにはそのようなオプションはありませんが、freebsd (net.inet.tcp .always_keepalive)

  • この機能を追加するためにLinuxカーネルにパッチを当てることは、私のシステム管理者にとって大きな問題でした;)

  • Java コマンド ライン引数の検索に失敗しました

  • 最後のオプション: setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(true)); を追加して、既存の JVM の java.net.PlainSocketImpl にパッチを適用します。保護された同期された void create(boolean stream) メソッドで、-Xbootclasspath/p を介して rt.jar の前に配置します

この最後のオプションはこれまでのところ機能していますが、このために JVM を変更する必要があったため、少しイライラしています。このような問題に対処するための他の/より良い方法を知っている人はいますか? すべての (Java) アプリケーションでデフォルトで SO_KEEPALIVE を有効にする別の簡単な方法がないのはなぜですか?

最後の質問: java API で serverSockets オブジェクトに keepAlive を設定できないのはなぜですか? Socket オブジェクトでのみ可能ですが、実際には serverSockets でも機能します

4

3 に答える 3

1

Java エージェント ( http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html ) および ASM4 ( http: //asm.ow2.org/ )。対象のクラスとメソッドがわかっているので、必要なのは、関連するメソッドのリターン バイトコード命令をキャッチし、その前にメソッド呼び出しを挿入することだけです。

于 2013-04-21T05:45:22.090 に答える