Upgrade to Pro — share decks privately, control downloads, hide ads and more …

非同期処理でも分散トレーシングしたい!- OpenTelemetry × Pub/Sub -

非同期処理でも分散トレーシングしたい!- OpenTelemetry × Pub/Sub -

Avatar for Tomonori Hayashi

Tomonori Hayashi

May 14, 2025
Tweet

More Decks by Tomonori Hayashi

Other Decks in Technology

Transcript

  1. Tomonori Hayashi • NTT コミュニケーションズ ◦ ソフトウェアエンジニア ▪ Front:TypeScript -

    React/Next.js ▪ Infra:Google Cloud • Google Cloud Partner Top Engineer 2024 - 2025 • Google Cloud Tech Blog Challenge 2024 個人カテゴリ受賞 • Google Cloud All Certifications • 社外コミュニティ ◦ Jagu’e’r (Google Cloud 公式ユーザーコミュニティ) ▪ エバンジェリスト ▪ オブザーバビリティ分科会 運営 2 @pHaya72 @t_hayashi
  2. 7 インフラレベルの非同期処理のつらみ 処理が分断されることで調査箇所が増える アプリケーションレベル インフラレベル Ex. 重い処理などでメインスレッドのブロッキングを防ぐためにバックグ ラウンドスレッドで非同期に処理する Ex. メッセージサービスを挟んで重い処理などを専用のサービスに任せ

    て非同期に処理する Service B の処理が失敗した場合 Service B のアプリケーションがバグる Service B のホストがバグる → Service B 内の話だから追跡しやすい Service B の入力がバグる → なぜこのようにバグったか追跡しづらい
  3. 8 インフラレベルの非同期処理のつらみ 処理が分断されることで調査箇所が増える アプリケーションレベル インフラレベル Ex. 重い処理などでメインスレッドのブロッキングを防ぐためにバックグ ラウンドスレッドで非同期に処理する Ex. メッセージサービスを挟んで重い処理などを専用のサービスに任せ

    て非同期に処理する Service B の処理が失敗した場合 Service B のアプリケーションがバグる Service B のホストがバグる → Service B 内の話だから追跡しやすい Service B の入力がバグる → なぜこのようにバグったか追跡しづらい 入力は Service A が送出しているから!
  4. 9 インフラレベルの非同期処理のつらみ 処理が分断されることで調査箇所が増える アプリケーションレベル インフラレベル Ex. 重い処理などでメインスレッドのブロッキングを防ぐためにバックグ ラウンドスレッドで非同期に処理する Ex. メッセージサービスを挟んで重い処理などを専用のサービスに任せ

    て非同期に処理する Service B の処理が失敗した場合 Service B のアプリケーションがバグる Service B のホストがバグる → Service B 内の話だから追跡しやすい Service B の入力がバグる → なぜこのようにバグったか追跡しづらい 入力は Service A が送出しているから! (もしかしたらメッセージキューもバグるかも)
  5. 10 一連のトレースになっていると嬉しい、けど・・ コンテキストの欠如 いわずもがなですが、コンテキストが伝播することで 分散トレーシングが可能となる Service A と Service B

    では PubSub などの メッセージキューを介することでコンテキストが 伝播せずに損失してしまう・・・ コンテキスト伝播の流れ これをどうにか解決したい!
  6. 11 直感的に思いつくのは・・ メッセージにコンテキストを含める Service A がパブリッシュするメッセージに コンテキストを含める Service B がサブスクライブしてメッセージに含まれる

    コンテキストを利用して生成したスパンを紐づける オブザーバビリティツール上で非同期処理でも 一連のトレースとして観測することできる! コンテキスト伝播の流れ 受け渡すメッセージに コンテキストを含める もっとスマートに解決したい!
  7. 12 Pub/Sub には Otel オプションが存在する Client が自動でコンテキストを伝播させる パブリッシャー/サブスクライバーそれぞれで実装する Pub/Sub Client

    でオプションを有効化する コンテキスト伝播の流れ Pub/Sub サブスクライバーでの実装 パブリッシャーでの実装
  8. 13 Pub/Sub には Otel オプションが存在する Client が自動でコンテキストを伝播させる パブリッシャー/サブスクライバーそれぞれで実装する Pub/Sub Client

    でオプションを有効化する コンテキスト伝播の流れ 受け渡すメッセージに コンテキストを含める サブスクライバーでの実装 パブリッシャーでの実装 Pub/Sub が受け取るメッセージ Pub/Sub
  9. 14 Pub/Sub には Otel オプションが存在する Client が自動でコンテキストを伝播させる パブリッシャー/サブスクライバーそれぞれで実装する Pub/Sub Client

    でオプションを有効化する サブスクライバーでの実装 パブリッシャーでの実装 ServiceA ServiceB ServiceA Pub/Sub Client
  10. 15 せっかくなのでコードを見てみる Pub/Sub Client のコード パブリッシャーが publish するタイミングで _open_telemetry_enabled が

    True だと start_create_span 関数や start_publisher_flow_control_span 関数が 実行される 引用:https://github.com/googleapis/python-pubsub/blob/main/google/cloud/pubsub_v1/publisher/client.py
  11. せっかくなのでコードを見てみる Pub/Sub Client のコード start_create_spant 関数 Tracer を取得してスパンを生成 ・ユーザーがパブリッシュした _message.data

    ・ attributes には色々含まれている Event のスパンへの紐付け TraceContextTextMapPropagator で伝播 ・Pub/Sub に送られるメッセージの attributes key の googleclient_traceparent を つっこんでいる 引用:https://github.com/googleapis/python-pubsub/blob/main/google/cloud/pubsub_v1/open_telemetry/publish_message_wrapper.py どうやって伝播している?
  12. 17 【再掲】Pub/Sub には Otel オプションが存在する Client が自動でコンテキストを伝播させる パブリッシャー/サブスクライバーそれぞれで実装する Pub/Sub Client

    でオプションを有効化する コンテキスト伝播の流れ 受け渡すメッセージに コンテキストを含める サブスクライバーでの実装 パブリッシャーでの実装 Pub/Sub が受け取るメッセージ Pub/Sub
  13. せっかくなのでコードを見てみる OpenTelemetry-Python のコード TextMapPropagator クラス サービス間でトレース情報を伝播させるための インターフェース HTTPリクエスト/レスポンスヘッダーや メッセージキューのメタデータ などの

    テキスト形式で情報( = carrier) をやりとりする場面で利用 Inject 関数 現在の context(もしくは指定されたもの) からコンテキスト情報を取得して 指定の setter 関数を使って carrier に コンテキスト情報を書き込む どんな情報を書き込んでいるか? 引用:https://github.com/open-telemetry/opentelemetry-python/blob/main/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py
  14. せっかくなのでコードを見てみる Pub/Sub Client のコード start_create_spant 関数 Tracer を取得してスパンを生成 ・ユーザーがパブリッシュした _message.data

    ・ attributes には色々含まれている Event のスパンへの紐付け TraceContextTextMapPropagator で伝播 ・Pub/Sub に送られるメッセージの attributes key の googleclient_traceparent を つっこんでいる → よくあるスパン生成とメッセージへの コンテキスト伝播が実直に行われていた 引用:https://github.com/googleapis/python-pubsub/blob/main/google/cloud/pubsub_v1/open_telemetry/publish_message_wrapper.py
  15. Pub/Sub をメッセージキューとして採用した非同期処理を構築 • 非同期処理では処理が分断されることでトラシューが面倒に • 分散トレーシングもコンテキストが損失されることで一連にならない Pub/Sub Client の Otel

    オプションの有効化で非同期処理でも分散トレーシング • オプションの有効化によってコンテキストがメッセージに含められる • 内部では TextMapPropagator が carrier へのコンテキスト書き込みをやってくれている → 非同期処理でも楽しいトラブルシューティングライフが送りましょう! まとめと学び
  16. CREDITS: This presentation template was created by Slidesgo, and includes

    icons by Flaticon, and infographics & images by Freepik Thanks! 21 @pHaya72 @t_hayashi