要件:マイクロサービスアーキテクチャでは、問題に直面した際にトラブルシューティングが非常に困難になることが多いです。なぜなら、それがサービスによる例外なのか、サービス自体がバグを書き込んでいるのか、あるいはサービスを呼び出すサービスが送信する情報に問題があるのか分からないからです。 すべてのリクエストのコンテキスト、すなわちトランザクション全体のリクエストへのリンクを記録できる場合、問題のトラブルシューティングと分析が非常に重要です。
復習:
例外スタックトレースは、モノリシックアプリケーションシステムのような単一のプロセスを対象としたアプリケーションに最適です。 しかし一方で、マイクロサービスアーキテクチャのような分散アプリケーションを扱う場合、スタックトレースだけでは全体のメッセージトレースを示すには不十分です。 これが分散トレーシングツールや標準が必要となる理由です。 W3Cはこの種のトレースに対して「トレースコンテキスト」と呼ばれる標準を定義しています。
トレースコンテキスト標準
W3C トレースコンテキストドキュメント:ハイパーリンクのログインが見えます。
W3Cトレースコンテキスト仕様は、分散トレースコンテキスト情報を伝播するためのHTTPヘッダーの標準とフォーマットを定義しています。 HTTPリクエストヘッダーでトレースフローを伝播させるために使われる2つのフィールドを定義しています。 標準定義の2つのフィールドを見てみましょう。
- traceparent: 用来描述在追踪图谱中到达请求的位置。它表示在追踪系统中到达请求的通用格式,被所有的 vendor 所理解。
- tracestate: 使用 vendor 特定的数据表示形式来扩展 traceparent,使用 name/value 对形式。在 tracestate 中保存信息是可选的。
トレースペアレントフィールド
トレースペアレントフィールドの仕様は拡張バコスパダイム(ABNF)の形で定義され、4つの部分から成ります。
バージョン - traceid - parentid/spanid - traceflags 例えば:
00-480E22A2781FE54D992d878662248d94-B4B37B64bb3F6141-00
- version: 8 位,系统适配的追踪上下文版本,当前位 00
- trace-id: 16 字节,追踪整体的标识。用于在系统中标识一个分布式追踪整体,同じリンクで値はまったく同じです。
- Parent-ID/SPAN-ID:インバウンドリクエストまたはアウトバウンドリクエストで現在のスパンの親を表現するための8バイト。
- trace-flags: 8 位,调用者的建议标志,可以考虑为调用者的建议,限制为 3 个原因:信息或是滥用,调用方的错误,或者在调用方与被调用方的不同负载。
すべてのフィールドは下の画像のように16進数でエンコードされています。
.NET 分散トレーシング
分散トレーシングは、特に複数のコンピュータやプロセスに分散しているアプリケーションにおける故障やパフォーマンスの問題を、エンジニアが位置を特定するのを支援する診断技術です。 この技術は、アプリケーション内のリクエストトラッキングを通じて異なるアプリケーションコンポーネントが行う作業を関連付け、同時要求を処理する際にアプリケーションが行う他の作業から分離します。 例えば、ロードバランサーはまず典型的なウェブサービスのリクエストを受け取り、それをウェブサーバープロセスに転送し、データベースに複数のクエリを発行することがあります。 分散トレースを用いることで、エンジニアはこれらのステップが失敗したかどうか、各ステップにかかる時間、各ステップ実行時に記録されるメッセージを区別できます。
.NETでは、System.Diagnostics.ActivityライブラリがW3C標準を使用するように設定されています。 W3CスタイルのトレースペアレントヘッダーであるRequest-Idヘッダーは、Core 2.0で追加 ASP.NET されました。 W3Cのトレースコンテキストに準拠したtraceparentヘッダーに変更するには、プログラム起動時にActivity.DefaultIdFormatのstaticプロパティをW3Cに設定してください。 コードは以下の通りです:
試験プロセス、ブラウザ -> A サービス(/http、バックエンドは HttpClient を使って B サービスを要求) インターフェース -> B サービス(/test)インターフェースサービスAは自身のトレースコンテキストとサービスBのトレースコンテキストを出力し、コードは以下の通りです。
以下の図に示すようにサービスAとBを開始します。
ブラウザは以下の図のようにサービスAを開きます:
Id: 00-9891603e6c4921598951f425d98e4df7-bd06e8d507a43f42-00
TraceId: 9891603e6c4921598951f425d98e4df7
SpanId: bd06e8d507a43f42
ParentId:
レスポンス内容:{"id":"00-9891603e6c4921598951f425d98e4df7-8874f9b2f9c0702e-00","traceId":"9891603e6c4921598951f425d98951f425d98e4df7","spanId":"8874f9b2f9c0702e","parentId": "00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00","traceFlags":"None","isSampled":false}
--------------------------------------------------
Name: HttpHandlerDiagnosticListener
DateTime: 2025/12/22 9:37:22
Id: 00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00
TraceId: 9891603e6c4921598951f425d98e4df7
SpanId: e0336cc56a4f2150
ParentId: 00-9891603e6c4921598951f425d98e4df7-bd06e8d507a43f42-00
Key: System.Net.Http.HttpRequestOut.Stop, Value: { Response = StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{ 日付:2025年12月22日(月)01:37:21 GMT サーバー:ケストレル 転送エンコーディング:チャンク つながり:キープ・アライブ Content-Type: application/json; charset=UTF-8 }, Request = メソッド: GET, RequestUri: 'http://localhost.charlesproxy.com:5551/test', バージョン: 1.1, Content: <null>, ヘッダー:
{ トレーペアレント:00-9891603E6C4921598951F425D98E4DF7-E0336cc56A4F2150-00 }, RequestTaskStatus = RanToCompletion } -------------------------------------------------- チャールズプロキシパケットキャプチャツールを使用すると、リクエストとレスポンスは以下の通りです:
HttpClientがtraceparentのパスを無効にしたい場合は、環境変数を以下のように設定します:
参考:
ハイパーリンクのログインが見えます。
ハイパーリンクのログインが見えます。
ハイパーリンクのログインが見えます。
ハイパーリンクのログインが見えます。
ハイパーリンクのログインが見えます。
ハイパーリンクのログインが見えます。 |