EC2上のCoreOS内で動くDocker内のPlayアプリケーションのプロファイルを計測する


EC2上にCoreOSを動かし、そこでDockerコンテナを走らせている場合、JVMのプロファイルを取りたいと思っていたのですが、
どうもFlight Recorderがうまく動作しない気がしたので、EC2上のDocker環境で動くのを確認してみました。

EC2上にCoreOSを起動する。

こちらのCoreOSオフィシャルサイト から適当にCoreOSイメージを選択して起動します。

※ それっぽいボタン(右のLaunch Stack)を押すとCloudFormationで複数台起動することになるので注意。AMIのリンクを押して起動します。

EC2のインスタンスの作成はいろいろなところで解説されているのでそちらを参照して起動してください。

CoreOSにログインし、Dockerインスタンスを起動する。

ログインはEC2にsshする標準の方法で。CoreOSのイメージはユーザ名coreとなるので注意。

Dockerインスタンスの起動

Dockerのイメージは私が作成したCentOSにOracle JDK8がインストールされた以下のものを利用します。

docker run -p 80:9000 -id --name seed -v /var/tmp:/var/tmp chidakiyo/centos7-oracle-jdk8 /bin/bash

Docker内に接続する

docker exec -it seed /bin/bash

Docker内でPlayアプリケーションを起動する。

必要なモジュールのインストール

yum -y install git unzip

Playのシンプルなアプリケーションを取得する

サンプルで取得したものを利用します。

git clone https://github.com/chidakiyo/sample-seed.git

Playアプリケーションのビルド

cd sample-seed  

./activator dist

Playアプリケーションの配置

unzip target/universal/play-scala-1.0-SNAPSHOT.zip -d /var/tmp/

Playアプリケーションをフライトレコーダを有効にして実行

cd /var/tmp/play-scala*  

./bin/play-scala -J-XX:+UnlockCommercialFeatures -J-XX:+FlightRecorder

Flight Recorderでプロファイルを取得を実行する

PIDを調べる

jcmd

を実行し、play.core.server.ProdServerStartが起動されているPIDを調べる

フライトレコーダでプロファイルの取得

jcmd {PID} JFR.start delay=1s duration=30s filename=/var/tmp/record_1.jfr

上記の例の場合、30秒間のみプロファイルの取得を行い/var/tmp配下にファイルを出力します。

JFRファイルの取得と表示

ファイルの取得

ファイルの取得はscpなどを利用して取得してください。

Dockerの/var/tmp/ディレクトリはCoreOSの/var/tmpをマウントして起動しているので、CoreOS内の/var/tmpディレクトリから取得できればOKです。

ファイルを見る

Oracle Java (7以降) がインストールされた環境で.jfrファイルをダブルクリックで実行します。

きれいなグラフなどJVMの詳細な情報が見れましたね。