本記事は「TUNA-JP Advent Calendar 2021」の3日目のエントリです。TanzuのOSSかといわれると、怪しいですが、VMwareが積極的に投資しているSpring Framework、その中でアプリケーションの可観測性を高めるSpring Sleuthについて紹介します。
まず、分散トレーシングって何?
この記事を分散トレーシングについて理解する必要があるのですが、これについてはシリーズ化した以下を参考にしてください。
要点を説明すると…
マイクロサービスなアプリケーションを以下のように可視化してどの処理がどのくらい時間かかったか、失敗している処理はなどがわかるようにする技術です。
OpenTracing, OpenCensus, OpenTelemetry ...
さて、この分散トレーシングを実装する技術として、様々な技術が登場しました。
古くは OpenTracing が有名でしたが、Githubのページをみると、2年以上更新が滞っているので、プロジェクトとしては終了状態です。
OpenCensusも同じ状況であり、これもGithubも更新されていないです。
OpenTracing, OpenCensus の終了に伴い、OpenTelemetry が現在一番アクティブなプロジェクトです。
この記事は OpenTelemetry を紹介する記事ではないので、詳細は割愛しますが、特徴として
• 既存コードをいじらなくても、AutoInstrumentation機能が豊富
• OTEL Collectorという形で、バックエンドの監視システムとの統合部分の依存度を減らすことで、メンテコストを減らす
といった点を持っています。
OpenTelemetryの登場により、分散トレーシングをより気軽にためすことができるようになりました。ただし、考慮点がまったくないわけではなく、執筆時点では何よりも「若い」といった問題があります。例えば、Javaのライブラリは2021の二月ごろに1.0.0からリリースされてから高頻度にリリースが繰り返されており(執筆時点でmavenで指定すると"1.9.1-alpha"という謎なバージョン)、決して安定しているという状況と言えないのが実情です。
Spring Cloud Sleuthが颯爽と登場
OpenTelemetryとは独立した形でSpring Framework(Javaのフレームワーク)に特化した分散トレーシングの実現方法がSpring Cloud Sleuthです。
特徴として、「安定」しているという点です。プロダクションでも多く利用されており、Springで開発する場合の分散トレーシングを実現する方法の一番のおすすめです。その他以下の特徴をもっており
- エージェントが不要。JDKさえあれば、どこでも試せる
- Spring BootのAutoConfiguration機能をつかっているため、既存コードをいじらなくてもつかえる
- AutoConfigurationが気にいらない場合もSpring Framework側で詳細なレベルまでカスタマイズできる方法を提供
さらに、Spring Cloud SleuthとVMwareのTanzu Observabilityとの連携機能も実装されています。Springを使っている場合、無料ライセンス(これも登録作業不要で、Spring BootのAutoConfigurationで作られる)で利用できるので、気軽に試すことできます。
早速試す
といわけで、早速試したいと思います。前提として、作業端末になんらかのOpenJDK(v8以上でOK)をインストールしてください。
1. Springのコードに雛形をダウンロードする
まず、Spring Bootのコードの雛形をつくります。本来は
https://start.spring.io
を経由してGUI経由でやる方法もありますが、以下CLIでやってしまいます。以下を作業ディレクトリーで実行してください。
curl https://start.spring.io/starter.tgz \
-d artifactId=DistraceDemo \
-d baseDir=distrace \
-d dependencies=web,cloud-starter-sleuth,wavefront \
-d packageName=advent2021.tuna.jp \
-d applicationName=DistraceDemo | tar -xzvf -
2. 簡単なRestAPIを書く
展開されたファイルのdistrace/src/main/java/advent2021/tuna/jp/DistraceDemoController.java
というファイルを新規作成します。中身は以下の通りです。
package advent2021.tuna.jp;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DistraceDemoController {
@GetMapping("/demo1")
public String demo(){
return "demo1";
}
}
3. 起動
以下のコマンドで起動します。
./mvnw spring-boot:run
起動後、別プロンプトで、数回以下のコマンドを実行してください。
curl localhost:8080/demo1
さて、起動プロンプトのログに以下のようなメッセージが出力されているはずです。
Connect to your Wavefront dashboard using this one-time use link:
https://wavefront.surf/us/XXXXXX
URLをアクセスしてみます。
4. Tanzu Observabilityを見る
さきほどのURLにログインすると、VMwareのTanzu Observabilityへリダイレクトされます。この際のアカウントはSpring BootのAutoConfigurationによって作られた無料アカウント(追加請求はないです。)なのでご安心を。
最初のページはおそらく以下のようなSpringのダッシュボードのはずです。
ここの説明だけでも別記事ができてしまうのですが、割愛して、上のタブのApplications > Tracesを開きます。
すると以下のようなダッシュボードが開かれ、分散トレーシング、すなわちアプリケーションの監視を行えるダッシュボードが開きます。
5. アプリに外部依存関係を定義する
さて、先ほどの画面ですが、パッと見は面白いのですが、モノリスなアプリケーションだとあまり恩恵がありません。
そこでほんのちょっとだけコードをいじります。
Spring Cloud Sleuthのメリットとして、コードから透過的に分散トレーシングを実装できることでしたが、さらに明示的に見たい部分を追加するといったこともできます。今回はDBの接続をみれるようなコードを作ります。なお、本当のDBではないので、あくまでサンプルです。
ここでは、@NewSpan
アノテーションを使い、明示的に処理の可視化をできるようにしていきます。
distrace/src/main/java/advent2021/tuna/jp/ExternalService.java
という新規ファイルを作成し、中身をいかにしてください。
package advent2021.tuna.jp;
import org.springframework.cloud.sleuth.annotation.NewSpan;
import org.springframework.cloud.sleuth.annotation.SpanTag;
import org.springframework.stereotype.Component;
@Component
public class ExternalService {
@NewSpan
void mysql(
@SpanTag("span.kind") String spanKind,
@SpanTag("component")String component,
@SpanTag("db.type") String dbType,
@SpanTag("db.instance") String dbInstance
){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
さらに、distrace/src/main/java/advent2021/tuna/jp/DistraceDemoController.java
をもう少しいじります。
package advent2021.tuna.jp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DistraceDemoController {
@Autowired
private ExternalService externalService;
@GetMapping("/demo1")
public String demo(){
externalService.mysql(
"client",
"java-jdbc",
"MySQL",
"DB"
);
return "demo1";
}
}
この状態でアプリケーションを起動しなおします。(先ほど動いているものがあれば停止してください。)
./mvnw spring-boot:run
あがってきたら、再度何回か、コマンドをうちます。
curl localhost:8080/demo1
4. Tanzu Observabilityをもう一度、見る
Tanzu Observabilityにログインして、上のタブのApplications > Application Status を開きます。
すると以下のように、アプリケーションからデータベースの接続が図式化されています。
さらに、Applications > Tracesを見ます。
最新のTrace情報をみると、mysqlという処理が追加されていて、それが約1秒かかっている(なぜかはさきほど作ったコードを参照してみてください。)ということを図式することができました。
まとめ
OpenTelemetryが最近もりあがっていますが、お手軽さや安定性を考えた場合、Spring Cloud Sleuthは非常に強力なツールです。
本記事では、簡単に紹介させていただきました。