Vagrant内のJVMに対してJconsoleとか使う、JMX over SSH
Javaのパフォーマンス解析には、Jconsoleとか、VisualVM などを使う。
最初の小さなジレンマは、これらの解析ツールがGUIであることだ。私が使うテスト環境Vagrant内部にはGUIをインストールしてないため、Vagrant外部から解析したいわけだが、VMの外から中のポートはたたけない。ポートフォワーディングでいいかとおもいきや、単純にフォワードしてもダメだった。なぜかはよくわからない。
というわけで、今日は簡単な方法を発見したのでシェアだ。
SOCKS プロトコル
SOCKSというプロトコルがあるそうだ。クソなプロトコルのことではない。Socketsからきている。SOCKSは、あるポートにバインドした通信路へのソケットを提供してくれるらしい。これがTCP/IP全般を肩代わりできるらしいので、用途は広い。この通信路でSSHを経由してJMXを通す。ssh
にはこのSOCKSを使うことができるオプション-D
がついている。これと、バックグラウンド実行の-f
, リモートコマンド実行しない-N
をつけて、
ssh -fND $(PORT) vagrant@myenv
これで$(PORT)
番のポートにSOCKSができる。
Jconsoleから使う
jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=$(PORT) service:jmx:rmi:///jndi/rmi://localhost:$(JMX_PORT)/jmxrmi
これでいけた。
Visual VMから使う
jvisualvm -J-Dnetbeans.system_socks_proxy=localhost:$(JMX_PORT) -J-Djava.net.useSystemProxies=true
こっちはまだ試していないが、これでいけるらしい。
まとめ
今回の話は、vagrant内のJVMに限らない。Firewallで囲まれてる環境の外からJMXツールを使う場合は汎用的に使えるはずだ。 ただし、CUIから使うことに苦がない、RMIの呼び出しなどは、jmxtermがおすすめである。 グラフをGUIでみるなど外部からモニタリングしたい、かつ、プロダクションみたく監視ソフトウェアが充実している環境ではない場合に、使える小技である。
##参考
-
“ssh -Dとtsock”, 京大マイコンクラブ(KMC)
-
“JConsole over ssh local port forwarding”, stackoverflow,
-
“Tunnel VisualVM (JMX) over SSH”, BowerStudios.com,
« recoverでGoのテストのスタックトレースを省略する
Gitで一個前のコミットから作業したいケースと方法 »