そーだいなるらくがき帳

そーだいが自由気侭に更新します。

H2Oの監視 ~ mackerel-plugin-h2oを読み解く

この記事は Mackerel プラグインアドベントカレンダー(全部CRE) の22日目です。

qiita.com

soudai.hatenablog.com

それでは22日目は mackerel-plugin-h2o です。

mackerel-plugin-h2oは高速で動作する、HTTP/2にも対応したWebServerのH2O専用プラグインです。

github.com

インストールと設定手順

H2Oのプラグイン/server-status の内容を可視化してくれるプラグインです。

そのためH2Oのserver-statusを有効化する必要があります。

Status Directives - Configure - H2O - the optimized HTTP/2 server

認証は設定せずにシンプルな場合は下のようなconfになります。

user: root
hosts:
  "*":
    listen:
      port: 80
    paths:
      "/":
        file.dir: /usr/local/src/h2o/doc

      /server-status:
        status: ON

curl http://localhost/server-status/json で値が取れればOKです。

プラグインプラグイン集として提供しているパッケージの mackerel-agent-plugins に含まれています。 インストール先は mackerel-plugin-h2o です。

次にMackerelのプラグインはコマンドですので実行する事ができます。

※認証を設定している場合はオプションを利用して認証情報を入力しましょう

-- /usr/bin はPATHが通っているので省略出来ます
# mackerel-plugin-h2o -port 80 | wc -l
64

64メトリック…気合を入れて説明していきます。 設定ファイルであるmackerel-agent.confは標準では /etc/mackerel-agent/mackerel-agent.conf にインストールされます。

以上を行った上でmackerel-agentを再起動してください。

見れるメトリック

各グラフ定義ごとに説明します。 それでは各グラフ定義ごとに説明します。 また表に出てくるdiffとはプラグイン上で差分値計算をするかどうかです。 となっている項目はプラグインで前回の実行時の値と差分値計算して出力しています。

H2O Uptime

メトリック名(ラベル) プラグインの出力名 diff 説明
Seconds h2o.uptime.uptime 起動時間(秒)

H2Oが起動してからの時間です。 mackerel-plugin-uptimeの説明のときも話をしましたが、ミドルウェアの起動時間も同じく監視すると不意な再起動などを検知できます。

H2O Connections

メトリック名(ラベル) プラグインの出力名 diff 説明
Active connections h2o.connections.connections 現在のアクティブな接続数
Max connections h2o.connections.max_connections 最大接続数

こちらは接続数です。 最大値に対して現在どれくらい使っているかも一目瞭然です。 もちろんMaxを超えないように監視しましょう。

H2O Listeners

メトリック名(ラベル) プラグインの出力名 diff 説明
Listeners h2o.listeners.listeners 現在のリスナー数

H2Oで動いているlisten中のSocketの数です。 例えば80と443が有った場合はHTTP/1.1とHTTP/2で4つになります。

H2O Worker Threads

メトリック名(ラベル) プラグインの出力名 diff 説明
Worker Threads h2o.worker_threads.worker_threads 現在のワーカースレッド数

H2Oで動いているワーカースレッド数です。 max-workers を調整するときなどに接続数やリクエストなどと併せて確認しましょう。

H2O Sessions

メトリック名(ラベル) プラグインの出力名 diff 説明
Sessions h2o.num_sessions.num_sessions トータルセッション数

こちらはセッション合計数です。 増え方などでピークの時間帯や長い期間での成長率などが見えてきます。 ですので毎日1日分を見るだけでなく定期的に2週間などの長い期間でも確認するようにしましょう。

H2O Requests

メトリック名(ラベル) プラグインの出力名 diff 説明
In-flight Requests h2o.requests.requests リクエスト数

その名の通り、リクエスト数です。 コネクションと比較しながら見るのが良いでしょう。

H2O Status Errors

メトリック名(ラベル) プラグインの出力名 diff 説明
Error 503 h2o.status_errors.status_errors_503 1分間あたりのエラーコードが503の数
Error 502 h2o.status_errors.status_errors_502 1分間あたりのエラーコードが502の数
Error 500 h2o.status_errors.status_errors_500 1分間あたりのエラーコードが500の数
Error 417 h2o.status_errors.status_errors_417 1分間あたりのエラーコードが417の数
Error 416 h2o.status_errors.status_errors_416 1分間あたりのエラーコードが416の数
Error 405 h2o.status_errors.status_errors_405 1分間あたりのエラーコードが405の数
Error 404 h2o.status_errors.status_errors_404 1分間あたりのエラーコードが404の数
Error 403 h2o.status_errors.status_errors_403 1分間あたりのエラーコードが403の数
Error 400 h2o.status_errors.status_errors_400 1分間あたりのエラーコードが400の数

HTTPステータスコード毎のERROR情報です。 デフォルトであるのはうれしいですね!! ちなみにエラーコードについては下記のリンクがわかりやすいです。

HTTPステータスコード

H2O HTTP2 Errors

メトリック名(ラベル) プラグインの出力名 diff 説明
Error protocol h2o.http2_errors.http2_errors_protocol 1分間あたりのError protocol
Error internal h2o.http2_errors.http2_errors_internal 1分間あたりのError internal
Error Flow Control h2o.http2_errors.http2_errors_flow_control 1分間あたりのError Flow Control
Error Setting Timeout h2o.http2_errors.http2_errors_settings_timeout 1分間あたりのError Setting Timeout
Error Frame Size h2o.http2_errors.http2_errors_frame_size 1分間あたりのError Frame Size
Error Refused Stream h2o.http2_errors.http2_errors_refused_stream 1分間あたりのError Refused Stream
Error Cancel h2o.http2_errors.http2_errors_cancel 1分間あたりのError Cancel
Error Compression h2o.http2_errors.http2_errors_compression 1分間あたりのError Compression
Error Connect h2o.http2_errors.http2_errors_connect 1分間あたりのError Connect
Error Enhance Your Calm h2o.http2_errors.http2_errors_enhance_your_calm 1分間あたりのError Enhance Your Calm
Error Inadequate Security h2o.http2_errors.http2_errors_inadequate_security 1分間あたりのError Inadequate Security

こちらはHTTP/2でのERRORを纏めています。

qiita.com

エラーハンドリング以外にもHTTP/2について詳しい解説がたくさんあってわかりやすいので上記のリンクもご参考ください。

H2O Read Closed

メトリック名(ラベル) プラグインの出力名 diff 説明
Read Closed h2o.read_closed.http2_read_closed 1分間あたりのRead Closed

H2O Write Closed

メトリック名(ラベル) プラグインの出力名 diff 説明
Write Closed h2o.write_closed.http2_write_closed 1分間あたりのWrite Closed

続けて2つ下記巻いたがそれぞれHTTP/2での書き込みと読み込みのcloseした数です。 H2OはHTTP/2に対する細かいモニタリングの配慮があって流石ですね。 またHTTP/2については下記の本が良いと社内で激推しされたのでこの冬休みの課題図書にしようと思います。




ここからは duration-stats をONにしないと取得されないメトリックです。 デフォルトはOFFになっており、公式ドキュメントにもある通り、 パフォーマンス劣化の原因 になりますのでご利用は計画的に。パフォーマンスを犠牲にする代わりなんとパーセンタイルで各メトリックを取得できます。 そのため、一見早く返しているように見えるが一部めちゃくちゃ遅いレスポンスが有る。などが一目瞭然です。 この機能はステージングなどでも効果的でしょうし、本番でも一部のServerだけ有効にするなどの使い方もアリだと思います。 ちなみにOFFになっている場合は常に0を返します。

H2O Connect Time

メトリック名(ラベル) プラグインの出力名 diff 説明
99 Percentile h2o.connect_time.connect_time_99 99パーセンタイルの数
75 Percentile h2o.connect_time.connect_time_75 75パーセンタイルの数
50 Percentile h2o.connect_time.connect_time_50 50パーセンタイルの数
25 Percentile h2o.connect_time.connect_time_25 25パーセンタイルの数
0 Percentile h2o.connect_time.connect_time_0 0パーセンタイルの数

接続してから最初のRequestを受け取るまでの時間です。

H2O Header Time

メトリック名(ラベル) プラグインの出力名 diff 説明
99 Percentile h2o.header_time.header_time_99 99パーセンタイルの数
75 Percentile h2o.header_time.header_time_75 75パーセンタイルの数
50 Percentile h2o.header_time.header_time_50 50パーセンタイルの数
25 Percentile h2o.header_time.header_time_25 25パーセンタイルの数
0 Percentile h2o.header_time.header_time_0 0パーセンタイルの数

リクエストを受け取ってからBodyのファーストバイトを受け取るまでの時間です。

H2O Body Time

メトリック名(ラベル) プラグインの出力名 diff 説明
99 Percentile h2o.body_time.body_time_99 99パーセンタイルの数
75 Percentile h2o.body_time.body_time_75 75パーセンタイルの数
50 Percentile h2o.body_time.body_time_50 50パーセンタイルの数
25 Percentile h2o.body_time.body_time_25 25パーセンタイルの数
0 Percentile h2o.body_time.body_time_0 0パーセンタイルの数

Bodyのファーストバイトを受け取ってからBodyを全て受け取るまでの時間です。

H2O Request Total Time

メトリック名(ラベル) プラグインの出力名 diff 説明
99 Percentile h2o.request_total_time.request_total_time_99 99パーセンタイルの数
75 Percentile h2o.request_total_time.request_total_time_75 75パーセンタイルの数
50 Percentile h2o.request_total_time.request_total_time_50 50パーセンタイルの数
25 Percentile h2o.request_total_time.request_total_time_25 25パーセンタイルの数
0 Percentile h2o.request_total_time.request_total_time_0 0パーセンタイルの数

リクエストの全てを受け取るまでの時間です。

H2O Process Time

メトリック名(ラベル) プラグインの出力名 diff 説明
99 Percentile h2o.process_time.process_time_99 99パーセンタイルの数
75 Percentile h2o.process_time.process_time_75 75パーセンタイルの数
50 Percentile h2o.process_time.process_time_50 50パーセンタイルの数
25 Percentile h2o.process_time.process_time_25 25パーセンタイルの数
0 Percentile h2o.process_time.process_time_0 0パーセンタイルの数

リクエストを受け取ってからレスポンスを返し始めるまでの時間です。

H2O Response Time

メトリック名(ラベル) プラグインの出力名 diff 説明
99 Percentile h2o.response_time.response_time_99 99パーセンタイルの数
75 Percentile h2o.response_time.response_time_75 75パーセンタイルの数
50 Percentile h2o.response_time.response_time_50 50パーセンタイルの数
25 Percentile h2o.response_time.response_time_25 25パーセンタイルの数
0 Percentile h2o.response_time.response_time_0 0パーセンタイルの数

レスポンスを返し始めてから返し終わるまでの時間です。

H2O Duration

メトリック名(ラベル) プラグインの出力名 diff 説明
99 Percentile h2o.duration.duration_99 99パーセンタイルの数
75 Percentile h2o.duration.duration_75 75パーセンタイルの数
50 Percentile h2o.duration.duration_50 50パーセンタイルの数
25 Percentile h2o.duration.duration_25 25パーセンタイルの数
0 Percentile h2o.duration.duration_0 0パーセンタイルの数

リクエストを受けてからレスポンスを返し終わるまでの時間です。

この辺は特に公式ドキュメントに明記されてなかったでソースコードの下記を参考にしています。 違ったら id:kazuhooku さんからありがたいご指摘をいただけると思っています!

h2o/h2o.h at master · h2o/h2o · GitHub

今日もなかなかの長編でした! Apache、Nginxよりも速いと言われているH2Oですがそれだけでなく、HTTP/2を使っていく人たちにとっては、モニタリングの視点から見ても良い選択肢の一つです。 ぜひこの機会に触ったことが無い方も触ってみてください!!

22日目はWeb ServerがH2O プラグインについての説明でした。 明日はネットワーク機器と言えばこれ!SNMPの監視です。 引き続き、Mackerel プラグインアドベントカレンダーをお楽しみに!

23日目 mackerel-plugin-snmp