Wavefrontで学ぶ分散トレーシング Part-3
この文章は、Wavefrontで学ぶ分散トレーシング シリーズの第三回目です。
シリーズ
第一回 : 概要編
第二回 : Spring Bootで分散トレーシング
第三回 : REDメトリクスって何? ← いまここ
第四回 : サービスをつなげてみる
第五回 : Pythonで分散トレーシング
第六回 : AMQPで分散トレーシング
第七回 ; サービスメッシュで分散トレーシング
始めに
前回Wavefrontで簡単なアプリで分散トレーシングをしましたが、以下の画面がでてきたと思えます。
画面最初のペインは3行で構成されていますが、これはREDメトリクスをベースに作成されています。
REDメトリクスとは Rate, Error, Durationの頭文字で、元々はWeaveworksのTom Wilkie氏が提唱した考え方です。
Wavefrontでは、各サービスの分散トレーシングのREDメトリクスを表示し、それぞれを測れるようにしています。 なお、Durationが見慣れないP95という表示になっていますが、これはパーセンタイル95%を表しています。あえて、ざっくりとした説明をしますが、これはやってきた全てのリクエストの95%目の遅いリクエストを表示しています。
さて、前回のデモでは特にErrorやDurationで面白い結果が表示されていないと思います。 今回はもうすこしこのREDについて理解を深めようというものです。
ここからの手順はほとんど前回と一緒ですが、微妙に違う箇所もあります。
準備編
Spring BootはJavaのフレームワークです。そのため、最低限以下が必要です。
- Java JDK 8+
Oracle JDKに従いJDKをインストールしてください。
ソースコード
ここに公開しています。
https://github.com/mhoshi-vm/wf-demanabu-dis-tracing/tree/master/3
アプリの準備
準備ができたら、以下のURLにアクセスしてください。
ログイン後、以下を実施します。
- Add Dependencies を選択
- Spring Webを検索して追加
- Sleuth も同様に追加
- Wavefront も同様に追加
最後にGenerateをクリックします。 すると、zipファイルのダウンロードされるので、どこでもいいので展開してくだい。
お気に入りのエディターで以下のファイルを開いてください。
1mhoshino@mhoshino demo % vi src/main/java/com/example/demo/DemoApplication.java
これを以下の内容に差し替えてください。
1
2package com.example.demo;
3
4import java.util.Map;
5
6import org.slf4j.Logger;
7import org.slf4j.LoggerFactory;
8import org.springframework.boot.SpringApplication;
9import org.springframework.boot.autoconfigure.SpringBootApplication;
10import org.springframework.http.ResponseEntity;
11import org.springframework.web.bind.annotation.GetMapping;
12import org.springframework.web.bind.annotation.RequestHeader;
13import org.springframework.web.bind.annotation.RestController;
14
15@SpringBootApplication
16public class DemoApplication {
17
18 public static void main(String[] args) {
19 SpringApplication.run(DemoApplication.class, args);
20 }
21
22}
23
24@RestController
25class HelloRestController {
26
27 private static final Logger LOGGER = LoggerFactory.getLogger(HelloRestController.class);
28
29 @GetMapping("/hello")
30 public ResponseEntity<String> hello (@RequestHeader Map<String, String> header) throws InterruptedException{
31
32 printAllHeaders(header);
33
34 // Generate bad request 10%
35 if ((long)(Math.random()*10%10) == 1) {
36 return ResponseEntity.badRequest().body("Good Bye World!");
37 }
38 int randomNumber = (int) (Math.random()*100);
39
40 if (randomNumber > 97) {
41 // Wait for 5 seconds in 2%
42 Thread.sleep(5000);
43 }else if (randomNumber > 90) {
44 // Wait for 2 seconds in 10%
45 Thread.sleep(2000);
46 }
47 return ResponseEntity.ok("Hello World!");
48 }
49
50 private void printAllHeaders(Map<String, String> headers) {
51 headers.forEach((key, value) -> {
52 LOGGER.info(String.format("Header '%s' = %s", key, value));
53 });
54 }
55}
さらに以下のファイルを開きます。
1mhoshino@mhoshino demo % vi src/main/resources/application.properties
そして以下の内容を追記します。
1management.endpoints.web.exposure.include=wavefront
2server.port=8082
3wavefront.application.name=demo2
4wavefront.application.service=HelloRED
コード編集は以上です。
試してみる
それではアプリケーションを稼働させます。 以下のコマンドを実行してください。
1mhoshino@mhoshino demo % ./mvnw spring-boot:run
うまくいけば、エラーなくアプリケーションが起動するはずです。 別プロンプトを開いて以下のコマンドをしばらく実行します。
1watch -n 0.1 curl localhost:8082/hello
さて5分ほどながしたら、サービスダッシュボードを見てみましょう。 これは、前回と同じく以下のURLでアクセスできるはず。
https://localhost:8082/actuator/wavefront
REDを分析する
しばらくすると、概ね以下のような図になるかと思います。
さて、この結果と実際のコードを照らし合わせてみましょう。 まず、Errorの以下の値をみてましょう。
これは以下のコードの結果です。 要は、10%の確率でエラーに陥らせた結果です。
1
2 // Generate bad request 10%
3 if ((long)(Math.random()*10%10) == 1) {
4 return ResponseEntity.badRequest().body("Good Bye World!");
5 }
なのでこれは結果どおりかと思います。
さて面白いのが以下のDuration(P95)の結果です。
さて一番遅いのが2秒と結果が出ていますが、以下がコードの結果です。
1
2 if (randomNumber > 97) {
3 // Wait for 5 seconds in 2%
4 Thread.sleep(5000);
5 }else if (randomNumber > 90) {
6 // Wait for 2 seconds in 10%
7 Thread.sleep(2000);
8 }
注目がこのコードは本来2%の確率で5秒まつが10%の確率で2秒まつとしている点です。 実際すこしスクロールダウンすると、実際には5秒待ちを検知しているのがわかります。 しかし、結果からわかるとおり、5秒まつの結果が無視されます。これが「パーセンタイル 95%」の意味です。要は、高い値の95% 以上の確率で発生する遅延はエラー値として、無視するという考えです。
この値に関して、色々考え方があるとは思いますが、とりあえず現段階で知って欲しいことはWavefrontがこういった分析結果を表示できる点です。(しかもタダで)
まとめ
- REDメトリクスは、Rate Error Durationの頭文字
- WavefrontでもREDメトリクスを元に、分析できる
- パーセンタイル95%など難しい結果表示もWavefrontでできる
次回は「サービスをつなげてみる」です。