今日構築するシステムは、ある意味で10年前に構築したプログラムとは異なります。マイクロサービスはネットワーク境界を越えて相互に通信し、デプロイメントは四半期ごとではなく常時行われ、障害は予測できない方法で伝播します。しかし、ほとんどの組織は依然として、過去の時代により適用可能なツールと技術で品質と信頼性にアプローチしています。
従来のQAツールは、モノリシックなアプリケーション時代と一括デプロイメント向けに設計されていました。独立したテストチームが出荷前にシステム全体を監査できました。監視はサーバーステータスとアプリケーショントレースの観察のみでした。例外は手動で処理できるほど稀でした。
分散システムはこれらの前提を粉々に破壊します。6つのサービスが個別にデプロイされると、集中テストはボトルネックになります。ネットワーク分断、タイムアウト依存関係、またはカスケード過負荷から障害が発生する可能性がある場合、単純なヘルスチェックは楽観的すぎます。イベントが通常の運用としてカウントされるほど頻繁に発生する場合、アドホックな対応手順はスケールしません。
チームは共有ツールから始め、モニタリングとテストを導入し、最終的にサービスレベルの信頼性プラクティスを追加します。それぞれは単独では意味がありますが、一緒になると企業を分断します。
特定のことが難しくなります。サービスにまたがるものをデバッグするということは、形の異なるクエリ言語を持つロギングツール間を切り替えることを意味します。システムレベルの信頼性は、壊れたダッシュボードから手動で相関関係を見つけることを意味します。
品質と信頼性の基盤を構築することは、どの機能が最も価値を提供するかを定義し、統合を可能にするのに十分な一貫性を持って提供することです。3つのカテゴリが柱を形成します:オブザーバビリティインフラストラクチャ、自動テスト検証パイプライン、および信頼性契約です。
オブザーバビリティは分散アプリケーションの計測を提供します。システム動作のエンドツーエンドの可視性がなければ、信頼性の向上は暗闇の中での一発勝負です。プラットフォームはオブザーバビリティの3つの柱を組み合わせるべきです:共通フィールドスキーマを使用した構造化ロギング、共通ライブラリを使用したメトリクス計測、およびサービス境界を越えてリクエストをトレースする分散トレーシングです。
標準化も重要です。すべてのサービスが同じパターンのタイムスタンプ、リクエストIDフィールド、および重要度レベルをログに記録すると、クエリはシステム全体で確実に機能します。メトリクスに一貫性と共通ラベルを持つ命名規則がある場合、ダッシュボードはデータを意味のある方法で集約できます。トレースがコンテキストヘッダーを一貫して伝播する場合、どのサービスが関与しているかに関係なく、リクエストフロー全体をグラフ化できます。
実装は、意味のある場所で計測を自動化することです。手動計測は一貫性の欠如とギャップをもたらします。プラットフォームはデフォルトでオブザーバビリティを注入するライブラリとミドルウェアを備えているべきです。サーバー、データベース、およびキューは自動的にログ、レイテンシ、およびトレースを計測すべきです。エンジニアはボイラープレートコードなしで完全なオブザーバビリティを持ちます。
2番目の基本的なスキルは、テストパイプラインを通じたテスト検証による自動テストです。すべてのサービスは、本番環境にデプロイする前に実行する必要がある複数レベルのテストが必要です:ビジネスロジックユニットテスト、コンポーネント統合テスト、およびAPI互換性契約テストです。プラットフォームは、テストフレームワークの提供、テスト環境のホスト、およびCI/CDシステムとのインターフェースによってこれを容易にします。
テストインフラストラクチャは、アドホックに管理されると、ボトルネックになります。サービスはテスト時にデータベース、メッセージキュー、および依存サービスが稼働していることを当然のことと考えています。依存関係の手動管理は、脆弱で頻繁に失敗するテストスイートを作成し、多くのテストを妨げます。プラットフォームは、依存関係を自動的にプロビジョニングし、データフィクスチャを管理し、実行間の分離を提供する管理されたテスト環境を提供することでこれを解決しました。
契約テストは分散システムで特に重要です。サービスがAPIを介して相互に通信する場合、単一のサービスでの破壊的変更がコンシューマーの破壊を開始する可能性があります。契約テストは、プロバイダーがコンシューマーの期待を満たし続けることを保証し、出荷前に破壊的変更をキャッチします。プラットフォームは契約の定義を容易にし、CIで契約を自動的に検証し、契約が破られているときに明示的なフィードバックを提供する必要があります。
3番目の柱は、SLOとエラーバジェットの形での信頼性契約です。これらは抽象的な信頼性目標を具体的で有形の形に落とし込みます。SLOは、可用性目標またはレイテンシ要件の形で、サービスにおける良好な動作を制限します。エラーバジェットはその逆です:SLOの制限内で許容される障害の量です。
コンセプトから運用プラットフォームへの移行には、誠実な優先順位付けが必要です。すべてを前もって構築することは、遅延した配信と戦略的でない機能への投資の可能性を保証します。職人技は、集中インフラストラクチャが短期的な価値を推進できる高レバレッジの優先領域を設定し、実際の使用状況に基づいて反復することです。
優先順位付けは理論的な完全性ではなく、痛点に基づいている必要があります。チームが今日苦しんでいる場所を認識することで、プラットフォームのどの領域が最も重要になるかを知らせます。一般的な痛点には、データが分散しているため本番の問題をデバッグするのに苦労する、安定した応答性のある方法でテストできない、デプロイメントが安全かどうかを知ることができないなどがあります。これらは直接プラットフォームの優先事項に変換されます:統一されたオブザーバビリティ、テストインフラストラクチャ管理、およびデプロイメント前の保証です。
活用すべき最初のスキルは一般的にオブザーバビリティの統一です。均一な計測を持つ共有ロギングとメトリクスバックエンドにサービスを配置することは、即座に配当を支払います。エンジニアは一箇所ですべてのサービスからログをドリルダウンし、コンポーネント間でメトリクスを相互相関させ、システム全体の動作を確認できます。データが単一の場所にあり、均一なフォーマットである場合、デバッグははるかに簡単になります。
ここでの実装は、移行ガイド、計測ライブラリ、およびロギングステートメントを新しいフォーマットに変換する自動化ツールを提供することです。サービスはビッグバンカットオーバーではなく、段階的に移行できます。移行中、プラットフォームは古いスタイルと新しいスタイルの共存を可能にし、移行パスと利点を明確に文書化する必要があります。
インフラストラクチャテストは自然に2番目の重要な機能として続きます。依存関係のプロビジョニング、フィクスチャ管理、およびクリーンアップを備えた共有テストインフラストラクチャは、すべてのチームから運用負担を取り除きます。また、エンジニアがテストを開発する場所と自動検証が実行される場所で、ローカル開発とCI実行を実行できる必要があります。
開始時の焦点は、サービスの大部分に適用される一般的なテストケースにあるべきです:テストデータを使用したテストデータベースのセットアップ、外部API依存関係のスタブ化、API契約の検証、および分離された統合テストの実行です。特別なテスト要件とエッジケースは、後続の反復で対処できます。早く十分に良いことは、後で完璧にするよりも良いです。
集中化と自由は均衡を保つ必要があります。過度の集中化はイノベーションを抑制し、特別な要件でチームを狂わせます。柔軟性が高すぎると、プラットフォームのレバレッジポイントが捨てられます。中間は意図的な脱出ハッチを持つ良いデフォルトです。プラットフォームはほとんどのユースケースに十分な意見のある回答を提供しますが、本当に特別な要件を持つチームは、プラットフォームの残りの部分を使用しながら、個々の部分から抜け出すことができます。
初期の成功は、将来の採用を容易にするモメンタムを生み出します。初期のチームがデバッグの効果やデプロイメント保証の実際の利益を見ると、他のチームが観察し、関心を持ちます。プラットフォームは、トップダウンで宣言されるのではなく、ボトムアップの価値を実証することで正当性を獲得します。ボトムアップの採用は、チームが何らかの利益のためにプラットフォームを使用することを選択するため、強制的な移行よりも健全です。
\


