この記事は GMOアドマーケティング Advent Calendar 2020 17日目の記事です。
こんにちは。
GMOアドマーケティングの@zakisanbaimanです。
GCPにプロファイラサービスがあるので試してみようと思います。
環境
- GCP
- CentOS7
- OpenJDK8
Cloud Profilerとは
Cloud Profiler は、本番環境のアプリケーションから CPU 使用率やメモリ割り当てなどの情報を継続的に収集する、オーバーヘッドの少ないプロファイラ。
Cloud Profiler のドキュメント
対応言語はGo, Java, Node.js, Pythonとなっています。
(2020年11月現在)
確認したいこと
プロファイル設定手順とプロファイル結果がどう表示されるのか。
設定手順
Java アプリケーションのプロファイリング
こちらの手順に従って進めていきます。
1. Profiler API を有効にする
1 |
$ gcloud services enable cloudprofiler.googleapis.com |
2. Profiler エージェントをインストールする
1 2 3 4 5 |
# Profiler エージェント用のインストール ディレクトリを作成 $ sudo mkdir -p /opt/cprof # エージェント アーカイブをダウンロード&展開 $ wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \ | sudo tar xzv -C /opt/cprof |
3. プロファイル対象のコードを配置
まずはシンプルにsleepで処理時間を変えてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class Main { public static void main(String[] args) throws InterruptedException { // 各メソッドを無限ループで呼び続ける while (true) { method1(); method2(); method3(); } } private static void method1() throws InterruptedException { System.out.println("method1"); // 1秒待機 Thread.sleep(1000); } private static void method2() throws InterruptedException { System.out.println("method2"); // 2秒待機 Thread.sleep(2000); } private static void method3() throws InterruptedException { System.out.println("method3"); // 3秒待機 Thread.sleep(3000); } } |
4. コンパイル&実行
Javaファイルの実行時にagentpathと共に先程インストールしたプロファイラのディレクトリを指定します。
agentpathフラグ
1 2 |
$ javac Main.java $ java -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=hello-world,-cprof_service_version=1.0.0 Main |
1分ほど流し続け(※)、その後Cloud Profilerの管理画面を見てみましょう。
※1回流すだけだとプロファイラに反映されませんでした。おそらく実行結果をいくつかサンプリングして反映しているものと思われます。
5. プロファイル結果確認
Java8において、指標は以下の2つをとることができます。
1. 経過時間
2. CPU時間
指標は各言語ごとに使えるものが決まっており、プロファイルの種類から確認することができます。
指標を「経過時間」にしてみると想定通りの時間配分になっています。
続いてCPU時間も確認したいのですが、sleepだけではCPU利用率は上がらないため、CPUを使う処理を別途作成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import java.io.File; import java.io.FileWriter; import java.io.IOException; public class CpuUsage { public static void main(String[] args) throws IOException { File file = new File("test.txt"); try{ FileWriter fileWriter = new FileWriter(file); method1(fileWriter); // 各メソッドを無限ループで呼び続ける while (true) { method1(fileWriter); method2(fileWriter); method3(fileWriter); } }catch(IOException e){ System.out.println(e); } } private static void method1(FileWriter fileWriter) throws IOException { for (int i = 0; i < 10; i++) { fileWriter.write("method1"); } } private static void method2(FileWriter fileWriter) throws IOException { for (int i = 0; i < 20; i++) { fileWriter.write("method2"); } } private static void method3(FileWriter fileWriter) throws IOException { for (int i = 0; i < 30; i++) { fileWriter.write("method3"); } } } |
1 2 |
$ javac CpuUsage.java $ java -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=cpu-useage,-cprof_service_version=1.0.0 CpuUsage |
指標を「CPU時間」にしてみると重い処理ほど大きく表示されます。
まとめ
ひとまずJavaプログラムをプロファイルすることができました。
どの処理にどれだけかかっているかが視覚的に捉えることができるので使いやすそうです。
クラウドサービスなので自前でサーバを構築する必要もないのも素晴らしいです。
このプロファイルツールを使って自社プロダクトのボトルネックを解消できればと思います。
ここまで読んで頂き、ありがとうございます。
参考
明日は、H.Tさんによる「Rubyのデバッガ「Ruby Jard」についてご紹介」です。
引き続き、GMOアドマーケティング Advent Calendar 2020 をお楽しみください!
■エンジニア採用ページ ~福利厚生や各種制度のご案内はこちら~
https://www.gmo-ap.jp/engineer/
■noteページ ~ブログや採用、イベント情報を公開中!~
https://note.gmo-ap.jp/