プロンプトと適用範囲
ある多言語マイクロサービスプラットフォームでは、OpenTracing API、ベンダーshim、およびOpenTelemetry SDKが使用されています。2026年3月以降、OpenTelemetryの仕様では新規実装に対するOpenTracing互換性の提供が不要となりましたが、既存のshimは移行期間中引き続き必要とされます。トレースを維持し、コストを制御し、単一サービス単位でのロールバックを可能にする移行計画を設計してください。
面接官がテストしていること
面接官は、あなたがAPI、データセマンティクス、およびバックエンドプロトコルの互換性を区別できているか、トレースとスパンの属性マッピング、コンテキスト伝播、サンプリングの一貫性、デュアルライトのコスト、ベンダーロックインを適切に扱えるかをテストしています。優れた回答とは、単に依存関係を置き換えるだけでなく、移行順序、受け入れ指標、および障害の隔離を提示できるものです。
最初に確認すべき質問
- どの言語やフレームワークがOpenTracingを使用しており、shimによってセマンティクスが変更されているか?
- バックエンドはOTLPを受け入れているか。また、過去データやクエリディメンションの安定性を維持する必要があるか?
- 優先事項はデータの欠落ゼロ、低オーバーヘッド、統一されたセマンティクス、ベンダーの代替可能性のどれか?
- 一時的なデュアルライトは許可されているか。また、サンプリングおよびサービスごとのコスト上限はどの程度か?
30秒での回答
「移行をAPI、セマンティクス、トランスポート、運用の各レイヤーに分割します。まず、新規のOpenTracing依存関係を凍結し、shim、伝播フォーマット、主要属性の棚卸しを行います。単一のサービスにおいて、shimを互換性用のエントリポイントとして維持しながらネイティブOpenTelemetryを追加し、単一のコンテキストとサンプリング決定を用いて両者を比較します。トレースの継続性、エラー率、属性カバレッジ、レイテンシ、コストが判定基準を満たしたら、言語や依存トポロジーごとに順次拡大します。障害発生時は、共有のCollectorプラットフォーム全体ではなく、該当サービスの受信またはエクスポートルートのみをロールバックします。」
ステップごとのソリューション
1. 呼び出しとセマンティクスの棚卸し
サービス、言語、OpenTracingパッケージ、shimバージョン、伝播フォーマット、およびエクスポートパスのインベントリを作成します。カスタムタグ、ログ、baggage、スパン名を洗い出し、それぞれをOpenTelemetryの属性、イベント、リンク、baggageにマッピングします。最も独自カスタマイズされたトレーサーからではなく、境界が明確なステートレスサービスから着手します。
2. 互換性の境界を定義する
アプリケーションコードをネイティブのOpenTelemetryトレーサーへ移行します。まだ変更できないライブラリのためにshimを保持しますが、shimへの新機能追加は凍結します。イングレス、非同期キュー、RPC、バッチの境界においてコンテキスト伝播の一貫性を維持する必要があります。API名が類似していても、同等のサンプリングや親子関係が保証されるわけではありません。
3. 制御されたデュアルライトの配置
ビジネスコード内で2つのスパンセットを生成するのではなく、SDKまたはCollectorのエクスポート境界での制御されたルーティングを優先します。デュアルライトが必要な場合は、サービスごとのサンプリング上限、キュー制限、リトライ、およびドロップ指標を設定し、「ビジネススパンが生成されなかった」のか「エクスポートに失敗した」のかを区別します。デュアルライト期間には明確な終了条件を設定します。
4. バックエンドのクエリ可能性を維持する
移行期間中は、サービス名、オペレーション名、ステータス、および重要なビジネス属性の名称を凍結します。同一のリクエストセットを新旧両方のパスに送信し、トレース数、親子関係、エラーステータス、レイテンシのパーセンタイル、エグゼンプラを比較します。バックエンドのクエリセマンティクスが変更される場合は、デフォルトビューを切り替える前にアダプターを提供するかダッシュボードを2系統用意します。
5. コストガードレールを設けたカナリア展開
言語、チーム、または依存ツリーごとにバッチ単位で移行します。エンドツーエンドのトレース継続性、スパンの欠落、Collectorキュー、CPUとメモリ、データ送信量(egress)、および100万スパンあたりのコストを追跡します。しきい値を超えた場合は、移行済みのサービスと生エビデンスを保持したまま、新規サービスの受け入れを停止します。
6. ライフサイクル制御を伴うロールバック
サービスごとにトレーサー初期化スイッチ、依存関係のバージョン、および構成スナップショットを保持します。共有Collectorリソースを削除するのではなく、該当サービスのエントリまたはエクスポートルートを切り替えることでロールバックを実行します。shimを削除する前に、ダウンストリームのライブラリがグローバルトレーサー経由でコンテキストを取得していないことを確認し、一定期間は互換性監視を継続します。
模範解答
新規のOpenTracing互換作業を凍結し、呼び出し、セマンティクス、伝播、エクスポートの棚卸しを行います。ネイティブOpenTelemetry APIへの移行はサービス単位で進め、変更不可能なライブラリはshimを介して維持しつつ、Context、サンプリング、属性マッピングをコントラクトテストで固定します。デュアルライトはSDKまたはエクスポート境界で制限し、継続性、属性カバレッジ、Collectorキュー、レイテンシ、コストの指標を監視します。言語および依存トポロジーに応じたカナリア展開を実施します。障害発生時は、構成、イベント、比較データを保持したまま、該当サービスの新規ルートを無効化して以前のエクスポートを復元します。shimの削除は、すべてのサービスが安定した後にのみ行います。
よくある間違い
- インポートの置換のみを行う → 親関係、baggage、または属性のセマンティクスが変更される → 伝播とセマンティックコントラクトをテストする。
- すべてのビジネス呼び出しでデュアルライトを行う → スパンボリュームとコストが急増する → SDKまたはエクスポート境界でルーティングを一元化し上限を設ける。
- Collectorの成功ステータスのみを監視する → アプリケーション側で既にスパンが欠落している → 生成、キューイング、エクスポート、バックエンドの各指標を分離する。
- 全サービスを一斉に移行する → 影響範囲が大きすぎる → 言語や依存トポロジーごとにカナリア展開する。
- 即座にshimを削除する → 未修正のライブラリの起動に失敗する → 新規依存関係を凍結し、参照が完全に存在しないことを確認する。
フォローアップの質問と回答
なぜ全チームに一斉の切り替えを要求しないのか?
共有ライブラリ、リリーススケジュール、言語SDKが異なるため、一斉切り替えは過大な障害影響範囲(ブラストレイディウス)を生み出します。階層化された互換性によりサービスの稼働を維持しつつ、新規開発の中心をネイティブAPIへと移行させることができます。
トレースが欠落していないことをどのように証明するか?
再現可能なリクエストに固定の識別子を注入し、イングレス、サービス間伝播、Collectorの受信、バックエンドのクエリ数を比較します。その上で、親リンク、ステータス、主要属性のサンプル検証を行います。
デュアルライトによってサンプリングが変わることはあるか?
はい。2つのトレーサーで個別にサンプリングを行うと、トレースの分断やコストの倍増が発生する可能性があります。共通のコンテキスト内でサンプリングを決定し、両方のルートがその決定を継承するようにします。
互換レイヤーはいつ削除できるか?
依存関係のスキャンでOpenTracingのエントリポイントが見つからず、コントラクトテストが伝播とセマンティクスをカバーし、カナリア指標が判定基準を満たし、保持期間中にロールバックが発生しなかった時点です。その後shimを削除し、監査ログを保持します。