JMXを特定のインターフェイスにバインドする方法は?
質問
現在、Java VMを com.sun.management.jmxremote。*
プロパティで起動しているので、JConsoleを介して管理および監視のために接続できます。残念ながら、マシン上のすべてのインターフェース(IPアドレス)でリッスンします。
この環境では、マシン上で同時に複数のJava VMが実行されている場合がよくあります。 ( com.sun.management.jmxremote.port
を使用して)別のTCPポートでリッスンするようにJMXに指示することはできますが、代わりにJMXに標準のJMXポートを使用させ、特定のIPアドレス(すべてではなく)。
これにより、JConsoleを介してどのVMに接続しているかを簡単に把握できるようになります(各VMが独自のIPアドレスを効果的に「所有」しているため)。誰もが単一のIPアドレスまたはホスト名でJMXをリッスンする方法を考え出しましたか?
解決
他の誰かがこれで彼の神経を失ったら... 10年後、彼らは最終的にそれを修正しました!
Java 8u102 -Dcom.sun.management.jmxremote.host
は選択したIPにバインドするため
他のヒント
フェルナンドはすでに私のブログ投稿へのリンクを提供しました:) ..それは簡単ではありません。必要なアドレスにソケットを作成する独自のRMIServerSocketFactoryImplを提供する必要があります。
内部/外部インターフェイスが問題であり、ローカルアクセスを設定している場合、ローカルファイアウォールを設定する方が簡単です。
これを試したことはありませんが、これで解決する可能性があります。
ここでの主な迷惑は、ホストIPを指定する簡単な方法がないことでした JMXがバインドするアドレス。常にすべてのインターフェイスにバインドします。の 「java.rmi.server.hostname」プロパティが機能せず、選択したくなかった 同じホスト上のすべての異なるインスタンスの異なるポート。
また、私はすべてのもので独自のRMIServerSocketFactoryを作成したくありませんでした それに関連する複雑さ、私は既存のコードへの簡単なパッチを求めていました。
デフォルトのJVM RMIソケットファクトリーにパッチを適用することでこれを修正しました このサーバーソケットの作成を担当します。現在、新しい 「com.sun.management.jmxremote.host」プロパティ。
これを機能させるには、以下のJavaコードを次の名前のファイルに保存します sun / rmi / transport / proxy / RMIDirectSocketFactory.java。
コンパイルしてjmx_patch.jarを作成し、tomcat lib /に配置します フォルダ。
次に、bin / setenv.shに次の行を追加する必要があります。
CLASSPATH = $ CLASSPATH:$ CATALINA_HOME / lib / mx_patch.jar
Tomcatインスタンスの起動時にこのオプションを追加
-Dcom.sun.management.jmxremote.host = 192.168.100.100"
これにより、JMXサービスがアドレス192.168.100.100にのみバインドされます。 2その他 ランダムなRMIリスニングポートは引き続きすべてのインターフェイスにバインドされますが、それで問題ありません とにかく常に無料のポートを選択するためです。
単一のホストで複数のTomcatインスタンスを実行できます。 デフォルトのポートはそのまま(例:JMXの場合はすべて8080)。
package sun.rmi.transport.proxy;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.server.RMISocketFactory;
public class RMIDirectSocketFactory extends RMISocketFactory {
public Socket createSocket(String host, int port) throws IOException
{
return new Socket(host, port);
}
public ServerSocket createServerSocket(int port) throws IOException
{
String jmx_host = System.getProperty("com.sun.management.jmxremote.host");
String jmx_port = System.getProperty("com.sun.management.jmxremote.port");
// Allow JMX to bind to specific address
if (jmx_host != null && jmx_port != null && port != 0 && integer.toString(port).equals(jmx_port)) {
InetAddress[] inetAddresses = InetAddress.getAllByName(jmx_host);
if (inetAddresses.length > 0) {
return new ServerSocket(port, 50, inetAddresses[0]);
}
}
return new ServerSocket(port);
}
}
試しました
-Dcom.sun.management.jmxremote.host =
openjdk 1.8を使用すると、うまく機能します。 (netstatに従って)そのaddessにバインドし、すべてが正しく見えます(そして動作します)。
受け入れられた答えはかなり古いです。 Javaがこれを可能にするいくつかのオプションを提供するという兆候がいくつかあります。たとえば、私は見ました:
-Djava.rmi.server.hostname=<YOUR_IP>
...同様に...
-Dcom.sun.management.jmxremote.host=<YOUR_IP>
ただし、少なくともjdk 1.7のシステムでは、これらは効果がないようです。JMXコネクタは引き続き*にバインドします。更新された回答(適用可能な特定のバージョン)をいただければ幸いです。これは簡単なはずです 。