メトリクスとトレースを使ったメモリリークの診断

OpenTelemetry が提供するようなアプリケーションテレメトリーは、分散システムの問題を診断するのに非常に役立ちます。 このシナリオでは、高レベルのメトリクスとトレースからメモリリークの原因を特定するまでの流れを実演します。

セットアップ

このシナリオを実行するには、デモアプリケーションをデプロイし、recommendationCacheFailure フィーチャーフラグを有効にする必要があります。 フィーチャーフラグを有効にした後、データが蓄積されるまで約10分ほどアプリケーションを実行してください。

診断

問題を診断する最初のステップは、問題が存在することを確認することです。 多くの場合、最初に確認するのは Grafana のようなツールが提供するメトリクスダッシュボードでしょう。

デモを起動すると、デモダッシュボードフォルダーに2つのダッシュボードが作成されます。 1つは OpenTelemetry Collector を監視するためのもので、もう1つは各サービスのレイテンシーとリクエストレートを分析するためのクエリとチャートを含んでいます。

Grafana ダッシュボード

このダッシュボードにはいくつかのチャートが含まれていますが、特に注目すべきものがあります。

  • レコメンデーションサービス(CPU% とメモリ)
  • サービスレイテンシー(スパンメトリクスから生成)
  • エラーレート

レコメンデーションサービスのチャートは、Prometheus にエクスポートされた OpenTelemetry メトリクスから生成されています。 一方、サービスレイテンシーとエラーレートのチャートは、OpenTelemetry Collector のスパンメトリクスプロセッサーを通じて生成されています。

ダッシュボードから、レコメンデーションサービスに異常な挙動があることがわかります。 CPU 使用率のスパイクに加え、p95、p99、p99.9 ヒストグラムでのロングテイルレイテンシーが確認できます。 また、このサービスのメモリ使用量にも断続的なスパイクが見られます。

アプリケーションからトレースデータも送信されていることがわかっているので、問題の存在を判断する別の方法についても考えてみましょう。

Jaeger

Jaeger を使うと、トレースを検索し、リクエスト全体のエンドツーエンドのレイテンシーを、個々の部分ごとに可視化して表示できます。 おそらくフロントエンドのリクエストでテイルレイテンシーの増加に気づいたかもしれません。 Jaeger を使えば、レコメンデーションサービスへのリクエストを含むトレースのみにフィルターして検索できます。

レイテンシーでソートすると、時間のかかった特定のトレースをすばやく見つけることができます。 右パネルのトレースをクリックすると、ウォーターフォールビューを表示できます。

Jaeger ウォーターフォール

レコメンデーションサービスの処理に長い時間がかかっていることがわかり、詳細を確認することで何が起きているかをより深く把握できます。

診断の確認

ウォーターフォールビューで、app.cache_hit 属性が false に設定されていること、そして app.products.count の値が非常に大きいことがわかります。

検索 UI に戻り、Service ドロップダウンで recommendation を選択し、Tags ボックスで app.cache_hit=true を検索してください。 キャッシュがヒットした場合、リクエストが速くなる傾向があることに気づくでしょう。 次に app.cache_hit=false で検索し、レイテンシーを比較してください。 トレースリストの上部にあるビジュアライゼーションにいくつかの変化が見られるはずです。

ここでは意図的に作られたシナリオなので、コード内のバグがどこにあるかはわかっています。 しかし、実際のシナリオでは、コード内で何が起きているか、あるいはそれを引き起こしているサービス間のインタラクションを見つけるために、さらなる調査が必要になるかもしれません。