ホームページ >バックエンド開発 >Python チュートリアル >openTelemetry と Signoz を使用したスパン リンクによるトレース分析をマスターする (実践ガイド、パート 2)
前のチュートリアルでは、スパン リンクを使用して分散システム内のインタラクションを追跡する方法を学習しました
このチュートリアルでは、スパン リンクを使用するためのベスト プラクティスと高度な使用例を実装する方法を見ていきます
複雑な分散システムを扱う場合、明確さとパフォーマンスを維持するには、適切なトレース戦略を選択することが不可欠です。
OpenTelemetry で自由に使用できる 2 つの主なツールは、親子関係とスパン リンクです。特に、より一般的な親子関係と比較して、スパン リンクを効果的に使用する場合と方法を検討してみましょう。
サービスの通信方法を正しくマッピングするには、親子トレースではなくスパン リンクをいつ使用するかを理解することが重要です。
親子関係: 標準トレース モデル
トレースにおける親子関係は簡単です。 1 つのサービスが別のサービスを呼び出すと、トレースによって 2 つのスパン間に直接の親子リンクが作成されます。子スパンは親スパンに依存しており、操作の流れを明確に示しています。
このモデルは、あるタスクが別のタスクを直接トリガーし、次のような線形進行をたどる同期操作でうまく機能します。
スパンリンク
実際のシステム、特にマイクロサービスや非同期プロセスを使用するシステムでは、すべての操作がこのきちんとした階層フローに従うわけではありません。ここで、スパン リンクが重要になります。
スパン リンクを使用すると、直接の原因と結果のパターンに従わない可能性がある 2 つのスパンを接続できます。例:
非同期タスク: メッセージ キューはリクエストを処理サービスに送信できますが、そのリクエストをトリガーした元のサービスに接続することもできます。
バッチ ジョブ: データをバッチで処理するシステムがあり、複数の子ジョブが 1 つのトリガー イベントにリンクされていますが、これらのジョブは順番に実行されません。
分離または非同期システム:
あるプロセスが別のプロセスを開始しますが、直接の呼び出しはありません。
複数の親: 複数のプロセスが 1 つの結果に寄与する場合 (たとえば、複数のサービスからのデータが 1 つのレポートに集約される)、スパン リンクを使用すると、関連するすべてのスパンを接続できます。
相関イベント: スパン リンクは、あるサービスでの障害が間接的に別のサービスでエラーを引き起こす場合など、異なるトレースからのスパンを関連付ける必要がある場合に最適です。
同期操作: タスク間の関係が直接的かつ同期的である場合、スパン リンクによって実際の価値が追加されずにトレースの視覚化が乱雑になる可能性があります。この場合、わかりやすくするために親子関係に限定します。
トラフィックの多いシステムでは、すべてのスパンまたはリンクをキャプチャする必要はありません。 サンプリングは、トレースの一部のみが記録される戦略であり、システムに負担をかけることなく、分析に十分なデータを確実に収集します。
ヘッドベースのサンプリング: これは、システムのエントリ ポイント (ヘッド) でトレースをキャプチャします。これを主要なサービスに適用して、優先度の高いまたは重要なトレースに対してのみスパン リンクが作成されるようにすることができます。
テールベースのサンプリング: これは、エラーが発生したトレースのみをキャプチャするなど、結果に基づいてトレースをサンプリングします。これを使用すると、障害など、詳細な調査が必要になる可能性が最も高いケースでスパン リンクが確実に使用されるようにすることができます。
特にスパン リンクが関係する場合、完璧な可観測性データを取得するには、適切な命名規則と構造化されたトレースが重要です。スパンの名前は、それが何を表すかを明確に説明する必要があります。スパン間の関係が必ずしも視覚的に明らかではないため、スパン リンクを使用する場合、これはより重要になります。
一貫した命名規則:
サービス名、機能、またはアクションを含めるなど、スパン名には一貫したパターンを使用します。 たとえば、支払い処理サービスのスパンには、payment-service.processPayment という名前が付けられます。
リンクされたスパンの役割を指定します:
必要に応じて、スパン名にリンクされたスパンの役割を示します。たとえば、user-authentication.request を session-creation.init にリンクすると、それらの間の接続が明確になります。
グループ関連スパン: 論理的にスパンをグループ化します。たとえば、複数のマイクロサービスが 1 つの大きなプロセスに寄与する場合、スパン リンクと名前付けが各部分を担当するサービスを識別するのに役立つことを確認します。
ドキュメント リンクの理由: 可能であれば、トレース自体 (メタデータ経由) またはドキュメントのいずれかで、スパン リンクが存在する理由を文書化してください。これは、2 つのスパン間の関係を説明するトレース コード内の短いコメントと同じくらい簡単です。
スパン リンクを使用してサービス間のエラー フローを追跡する方法
多数のマイクロサービスを含む複雑な Web アプリケーションを管理していると想像してください。各マイクロサービスは、ユーザー エクスペリエンスの異なる部分を担当します。
ユーザーが注文すると、支払いサービス、在庫サービス、配送サービスがトリガーされます。このチェーンのどこかでエラーが発生した場合、どこでエラーが発生し、他のサービスにどのような影響を与えたかを知ることが重要です。ここでスパンリンクが登場します。
スパン リンクを使用すると、直接の親子関係にないトレースを接続できますが、コンテキスト上の関連性は維持されます。エラー追跡にスパン リンクを使用すると、1 つのサービスのエラーとその後の他のサービスへの影響を関連付けることができます。たとえ直接的な関係がなかったとしても。
ユースケース: 決済サービスがトランザクションを処理しようとしているときにエラーが発生し、このエラーが配送サービスに間接的に影響を与えたとします。スパン リンクを使用すると、支払いサービスからのエラー スパンと、問題を検出した配送サービスのスパンとの間の関係を作成できます。
これは、サービス間のエラーの流れを視覚化し、その波及効果を理解するのに役立ちます。
マイクロサービス間のエラー スパンをキャプチャしてリンクするコード例
OpenTelemetry を使用してこれらのエラーをキャプチャし、エラー間にスパン リンクを作成する方法を見てみましょう。 Python を使用した簡単な例を次に示します:
from opentelemetry import trace # Initialize tracer tracer = trace.get_tracer("order-service") # Create a span in the payment service with tracer.start_as_current_span("payment-processing") as payment_span: try: # Simulate a payment process that raises an error process_payment() except Exception as e: payment_span.record_exception(e) payment_span.set_status(trace.Status(trace.StatusCode.ERROR, str(e))) # Capture the error trace and create a span link error_link = trace.Link(payment_span.get_span_context()) # Now in the shipping service, you can link this error trace with tracer.start_as_current_span("shipping-service", links=[error_link]) as shipping_span: # Handle the impact of the payment error here process_shipping()
上記のコードスニペットの説明
支払い処理スパンは、支払いが失敗したときのエラーをキャプチャします。
スパン リンク (error_link) は、支払い処理スパンのコンテキストを使用して作成されます。
このリンクは配送サービス範囲に追加され、支払いエラーが配送プロセスにどのような影響を与えるかを追跡できるようになります。
SigNoz などのツールを使用してこれらのエラーを視覚化し、問題の根本原因を特定するのがはるかに簡単になります。
実際の使用例: スパン リンクを使用して、マルチサービス アーキテクチャ全体にわたる顧客インタラクションを追跡する
現実世界のシナリオを考えてみましょう。注文などの顧客のアクションが、注文サービス、在庫サービス、支払いサービス、配送サービスなどの複数のサービスによって処理される電子商取引プラットフォームを想像してください。
単一の注文を行うユーザーは、サービスごとに 1 つずつ、複数のスパンを生成できます。
通常、これらのスパンは親子関係で配置され、注文サービスが支払いサービスなどの親になる場合があります。しかし、より複雑な関係を追跡したい場合はどうすればよいでしょうか?
たとえば、在庫サービスが支払い確認後に個別に在庫レベルをチェックする場合、それは支払いサービスの直接の子ではありません。スパン リンクを使用すると、これらのサービスを直接接続して、サービスがどのように相互作用するかをより正確に把握できます。
複雑なアーキテクチャでスパン リンクが重要な理由
スパン リンクにより、これらの非線形インタラクションを柔軟にキャプチャできるようになり、サービス全体にわたるユーザー アクションの包括的なビューが提供されます。これは、在庫確認による発送の遅延など、ユーザー エクスペリエンスのトラブルシューティングに特に役立ちます。
サーバーレスまたはイベント駆動型システムでスパン リンクが可観測性を強化する方法
サーバーレス システムまたはイベント ドリブン システムでは、サービスが相互に直接認識することなく、イベントによってアクションがトリガーされる分離された方法でサービスが対話することがよくあります。
たとえば、支払いサービスからのイベントは、イベント バスを通じて在庫更新サービスをトリガーする場合があります。これらのサービスには親子関係がないため、従来の方法で追跡するのは困難な場合があります。
サーバーレスでのスパン リンクの使用方法
スパン リンクは、これらのばらばらのサービス間の接着剤として機能します。イベントが 1 つのサービスから生成され、別のサービスによって消費される場合、元のイベントのスパンと消費側サービスのスパンを接続するスパン リンクを作成できます。
この方法では、サーバーレス関数が独立して実行されている場合でも、インタラクションの完全なストーリーを取得できます。
例: 支払い処理後に支払いサービスがメッセージをキューに送信し、このメッセージがサーバーレス アーキテクチャで在庫更新機能をトリガーするとします。
これらのスパンをリンクする方法のコード スニペットを次に示します
from opentelemetry import trace # Initialize tracer tracer = trace.get_tracer("order-service") # Create a span in the payment service with tracer.start_as_current_span("payment-processing") as payment_span: try: # Simulate a payment process that raises an error process_payment() except Exception as e: payment_span.record_exception(e) payment_span.set_status(trace.Status(trace.StatusCode.ERROR, str(e))) # Capture the error trace and create a span link error_link = trace.Link(payment_span.get_span_context()) # Now in the shipping service, you can link this error trace with tracer.start_as_current_span("shipping-service", links=[error_link]) as shipping_span: # Handle the impact of the payment error here process_shipping()
この設定により、非同期ではありますが、決済処理から在庫更新までの流れを追跡することができます。
視覚化すると、サーバーレス アプリケーションのさまざまな部分がどのように相互作用するかが明確になり、ボトルネックや予期せぬ遅延を診断する能力が向上します。
このアプローチが可観測性にとって重要である理由
従来のモニタリングでは、在庫の更新が遅いことが示される場合がありますが、スパンリンクを使用すると、その遅延をトリガーとなった特定の支払いイベントまで追跡できます。
このレベルの洞察は、システムを最適化し、スムーズなユーザー エクスペリエンスを保証するために非常に貴重です。
スパン リンクは、分散システムにおけるトレースの相関関係を大幅に強化できる OpenTelemetry の強力な機能で、十分に活用されていません。
しかし、それは正確には何を意味しますか?なぜ気にする必要があるのでしょうか?
アプリケーションをさまざまなサービスとプロセスのネットワークとして想像してください。すべてが通信して連携してユーザーのリクエストを満たすようにします。トレース間の単純な親子関係では、何が起こっているかの複雑さを完全に把握できないシナリオによく遭遇します。
たとえば、バックグラウンド ジョブがユーザー アクションによってトリガーされたイベントを処理している場合、または複数のサービスが非同期で連携している場合はどうなるでしょうか?ここで、課題を簡単に解決するためにスパン リンクが登場します。
それでは、スパンリンクを使用する利点は何でしょうか?
親子制約を超えた関連スパン:
スパン リンクを使用すると、親スパンと子スパンの一般的な階層構造に束縛されることなく、サービス間でトレースを接続できます。
これは、同時に発生するイベントを関連付けたい場合や、共通のコンテキストを共有しているが直接の親子関係がない場合に特に便利です。たとえば、ユーザー向けサービスのトレースをバックグラウンド プロセスにリンクすると、ユーザーのアクションがシステムのパフォーマンスにどのような影響を与えるかをより包括的に把握できます。
デバッグとトラブルシューティングの改善に役立ちます:
スパン リンクを使用すると、特に複雑なワークフロー中に、さまざまなサービスがどのように相互作用するかについて、より豊かな視点が得られます。リンクを介してどのスパンが関連付けられているかを確認することで、他の方法では発見するのが難しいボトルネック、エラー パターン、またはパフォーマンスの問題を特定できます。これにより、スパン リンクは、複数のサービスにまたがる問題をデバッグするための強力なツールになります。
非同期システムでの可視性が向上します:
メッセージ キューやイベント駆動型アーキテクチャを使用するアプリケーションなど、非同期処理に依存するアプリケーションの場合、スパン リンクは非常に貴重です。
タスクやメッセージがさまざまなサービスを通過する際のライフサイクルを追跡できます。これにより、システム全体にわたる 1 つのイベントの影響を理解し、プロセスの最適化と改良が容易になります。
つまり、スパン リンクを使用すると、アプリケーションの動作をより結び付けて意味のある全体像を作成できるようになり、可観測性が向上し、分散システムの動作方法をより深く理解できるようになります。
スパン リンクを効果的に活用することで、トレースの相関関係を強化し、トラブルシューティングを迅速化し、システムのパフォーマンスをより完全に把握できるようになります。
スパン リンクと関連概念に関する公式ガイダンスをさらに詳しく知りたい場合は、次のリソースが調査に役立ちます。
OpenTelemetry スパン リンクのドキュメント
これは、スパン リンクの作成および管理方法を理解するための頼りになるリファレンスです。スパンをリンクするための API 仕様について、サポートされているさまざまなプログラミング言語の例とともに説明します。これは、スパン リンクが内部でどのように機能するかという技術的な詳細を理解するための優れた出発点です。
OpenTelemetry コンテキストの伝播
コンテキストの伝播を理解することは、スパン リンクを最大限に活用するための鍵であり、このドキュメントでは、トレース全体でコンテキストがどのように管理されるかについて完全な概要を提供します。これは、分散サービス間でトレース データの一貫性を確保したい場合に特に役立ちます。
OpenTelemetry サンプリング戦略
スパン リンクを実装する場合、サンプリングがトレースにどのような影響を与えるかを知ることが重要です。ドキュメントのこのセクションでは、さまざまなサンプリング戦略を構成する方法に関する詳細なガイダンスを提供し、データの粒度とパフォーマンスの適切なバランスをとるのに役立ちます。
これらのリンクは、リファレンスと実際の応用の両方にとって貴重なリソースであり、OpenTelemetry のトレース機能を真剣に習得しようとしている人にとって不可欠なものとなっています。これらのリソースをブックマークし、より複雑な可観測性セットアップを構築する際のガイドとして使用してください。
ご質問や詳しい説明がございましたら、コメント欄で共有してください。
以上がopenTelemetry と Signoz を使用したスパン リンクによるトレース分析をマスターする (実践ガイド、パート 2)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。