本番環境におけるQA
2017年4月4日
システムに関する運用データ、特にCPUやメモリ使用量などのシステム負荷とパフォーマンスを示すメトリクスを収集することは一般的なプラクティスです。このデータは長年にわたり、システムをサポートするチームが、障害が発生しているか、または差し迫っているかを把握するのに役立てられてきました。システムが遅くなった場合、ボトルネックの原因となっているシステムの部分(例:実行速度の遅いデータベースクエリ)を特定するために、コードプロファイラを有効にすることがあります。
最近、この従来の運用監視の綿密さと、システムの品質に対するはるかに広範な視点とを組み合わせた傾向を観察しています。運用データはシステムをサポートする上で不可欠な部分ですが、システム全体が期待通りに動作しているかどうかを示す情報を提供するデータを集めることも価値があります。「本番環境におけるQA」とは、チームが本番システムの動作にさらに注意を払い、これらのシステムが提供する機能の全体的な品質を向上させるアプローチとして定義します。

本番環境では常に問題が発生しますが、これは悪いことではありません。 これは、システムと、システムが相互作用する現実の世界について学ぶ機会です。適切な本番監視ツールと優れた継続的デリバリーパイプラインがあれば、問題発生時にそれを検出し、迅速に修正プログラムをリリースするフィードバックメカニズムを構築できます。本番QA(品質保証)プラクティスを採用することで、システムが直面する実際の問題をより深く理解し、品質を向上させる新しい方法を学ぶことができます。
本番データの収集
システムに関する収集可能なデータは膨大です。システムの成功にとって重要なものは何かを考え、それらを参考に作業を進めることが非常に役立つと感じています。この文脈における成功とは、収益に繋がるようなものを指しています。システムが1秒間に何千ものリクエストを処理しても、顧客が支払うサービスや依存するサービスを提供できない場合は意味がありません。
重要な成功指標
私はTesで、教師が求人に応募するために使用するシステムの開発に携わってきました。私たちのチームが重要と判断したメトリクスの1つは、教師の求人応募が実際に応募先の学校に届いているかどうかです。システムは主にメールを使用して学校に新しい求人応募を通知します。メール送信にはサードパーティサービスを使用しているため、これは私たちが取り組んでいるシステムの境界の外にあります。私たちが学んだように、メール送信には多くの問題が発生する可能性があります。メールアドレスは、有効に見える場合でも無効な場合があり、メールボックスがいっぱいになる場合や、受信者が不在着信メッセージを持っているために、実際にメールを受信していても受信していないように見える場合があります。このような現実世界の複雑さは、予測がほとんど不可能であり、テストも困難です。そこで、本番環境で起こったことから学ぶことにしました。システムの品質に対する理解と対応がどのように進化したかの概要を以下に示します。
- 最初に、送信された求人数と送信したメール数をカウントしました(シンプルなメトリクスをメトリクスサーバーに送信することにより)。これらの数値が同期していない場合に通知されるアラートを設定しました。
- メール送信マイクロサービスがメール送信リクエストを処理できなかった場合に通知するアラートも設定しました。
- これは頻繁に発生することが判明しました。アラートは発報されましたが、その理由は不明でした。ログを確認しましたが、有用な情報は得られなかったので、ロギングの改善に取り組みました。特に、サードパーティのメールプロバイダーから受信したエラーに関する詳細なログを記録しました。
- ログから、さまざまな種類の応答について学びました。一部は、エラーにもかかわらず受信者がメールを受信した可能性があることを意味するものでした(例:不在着信返信)。一部(DNSの問題など)は一時的なものであり、一部のエラーはメールが配信されないことを意味していました。ドキュメントとエラーメッセージの一部は分かりにくかったので、未送信メールの例を使用して学校に連絡を取り、実際にメールが届いたものと届かなかったものを確認しました。
- メール送信コードがエラーの処理に厳しすぎることに気づいたので、少し緩和しました。(エラー応答が学校がメールを受信した可能性が高いことを意味する場合は、エラーのログを停止しました。)
- メールアドレスの入力ミスが原因で多くの問題が発生していることに気づきました。このような場合、ログを確認し、カスタマーサービスチームと連絡を取りました。「こんにちは。example@example.com にメールを送信しようとしましたが、送信できませんでした。メールアドレスが正しいかどうか学校にご確認ください。」
- しばらくの間、カスタマーサービスチームがメールアドレスが修正されたことを知らせてくれ、ウェブサービス上に構築したエンドポイントを使用して手動でメールの再送信をトリガーしました。しばらくして、メールアドレスが更新されたときにメールを自動的に再送信するようになりました。(メッセージキューで求人情報の更新を監視します。)
- 機能しないメールアドレスについてカスタマーサービスチームにメールを送信する作業がまだ多くあったため、これらのメールを自動的に送信するようになりました。
- この自動修復システムを導入したことで、ほとんどのメールが修正されているため、失敗したメールごとにアラートを発報しなくなりました。現在、アラートは、不良メールアドレスが問題なく処理されず、一定時間修正されない場合にのみ発報されます。
Tesの求人応募システムにとってもう1つの重要な使用状況メトリクスは、教師が実際に求人に応募しているかどうかです。求人応募フォームの最後に「送信」ボタンをクリックしたのか、それとも何かが妨げてクリックできなかったのか。小さなCSSやJavaScriptライブラリの変更によって、「送信」ボタンが特定のブラウザで正しく表示または動作しなくなった可能性があります。教師が応募を送信する頻度が減少すると問題の兆候となる可能性があるため、そのようなことが発生した場合に通知されます。また、サービスから返されたHTTP 500応答コードにも注意しています。教師に求人に応募してもらいたいので、何かがそれを妨げている場合は知りたいと思っています。私たちはこれについて非常に厳格なので、常に求人応募フォームを表示するためにできる限りのことを行います。フォームを表示するために必要なデータの取得で問題が発生した場合は、エラーをログに記録し、それでも問題が発生しているにもかかわらず、教師が応募できるように最善を尽くします。これらのログを確認し(アラートシステムが思い出させてくれます)、発生した問題に対処します。私たちは、潜在的な候補者を失望させるよりも、不良データやシステムの状態を修正したいと考えています。
これらの例では、本番データの収集にいくつかの異なる手法について説明しました。それらを詳しく見ていきましょう。
ロギング
ロギングは、データのログ記録方法に注意を払えば、システムに関するデータを収集するための非常に強力な方法です。ログは、システム管理者が何が間違っていたのかを調べるために精査する長いテキストファイルだけではありません。検索性を考慮してロギングスタックを構築すれば、システムに関する貴重なリアルタイムデータを提供できます。
ログは技術情報の記録に限定されません。貴重な使用状況データも記録できます。優れたロギングスタックを持つオンラインバンキングサイトで作業したことがありますが、そこでログを使用して、リリースした新機能の普及状況を判断できました。オンライン支払い限度額を調整できる機能をリリースし、この機能が広く採用されていることをすぐに確認できました。また、人々がどれくらいの頻度で、どの程度限度額を調整しているかについても興味深いデータを集めることができました。このようなロギングを行う場合は、ユーザーのプライバシーを考慮し、本当に必要なデータのみをログに記録することを忘れないでください。
より検索可能なログを実現する1つの手法は、ログ転送を使用することです。これは、サーバー上で実行されているソフトウェアを使用して、ログデータを定期的に別のサービス(通常は全文検索に最適化されたデータベース、例:ElasticSearchまたはApache Solr)に送信することによって行われます。このデータベースでクエリを構築することにより、時間の経過に伴う集計情報とトレンドを示す視覚化を作成できます。前述のバンキングサイトでは、送金された金額などの興味深いビジネスメトリクスと、ユーザーがバンキングに使用しているブラウザやデバイスなどのより技術的な情報を示すグラフを作成することができました。また、問題を検索して個々のログエントリにドリルダウンすることもでき、これは問題を調査する非常に効果的な方法です。
もう1つのアプローチは、構造化ロギングと呼ばれる手法を使用することです。これは、私がしばらく携わっていた保険会社で使用していました。次のようなログを記録する代わりに
There was an invalidInputFormat error capturing data for user 54321
次のようにログを記録できます。
There was an error capturing data for userId={54321},
errorType={invalidInputFormat}
個々のログエントリに少し構造を追加することにより、情報をより簡単に検索できるようになります。いくつかの強力なツール(例:Splunk)は、これらの種類のログに基づいてインデックスを作成し、最適化された検索、集計、視覚化を提供できます。ElasticSearchのようなツールを使用している場合は、JSON形式で構造化データをログに記録することもできます。
ログはより高度な方法で使用されるようになりましたが、ERROR、WARN、INFOなどのログレベルを指定するという実績のあるプラクティスを活用することを忘れないでください。このように各ログエントリの重大度をマークすることは、システムをサポートする際に非常に役立ちます。これは、ログの信号対雑音比が向上するためです。システムをサポートする担当者は、1日分のログを確認し、エラーのみを表示するようにフィルタリングできます(理想的には、これらのエラーはあまり多くありません)。このようにして、何も問題がなく、気づかずに済んだことを確認できます。
メトリクス
ログファイルへの情報記録に加えて、システムイベントの計数とシステムデータの集約を可能にするstatsdのようなツールがあります。ログは非常に具体的な情報を収集するのに役立ちますが、このアプローチは集約された情報を収集する方法を提供することで、ログを補完することができます。Tesでは、DataDogにデータを送信するためにstatsdを使用しています。例えば、各Dockerコンテナの現在のCPU負荷とメモリ使用状況を定期的に送信し、パフォーマンスの問題に気付くことができます。繰り返しますが、技術的なものだけでなく、ビジネス指標のキャプチャも検討することを強くお勧めします。
前述の求人応募システムでは、一般的なエラーの指標を送信しています。メールを送信するために、メッセージキューを介して共有マイクロサービスにメッセージを送信します。そのサービスがメッセージを処理できない場合、Dead Letter Queueにたどり着き、メッセージの1つがそのキューに入ったことを示す指標を送信します。この指標のインスタンスを受信した場合、チームは何か問題があり、調査する必要があることを警告されます。その後、メールサービスで同じ時間枠に発生したエラーをログで検索し、どの求人応募が学校にメールで送信されなかったか、エラーメッセージが何であったかを調べることができます。
また、アプリケーションの起動、更新、送信時など、一般的な使用状況の指標も収集します。これを使用して、応募されたアプリケーションの割合を確認し、さまざまな種類の応募フォームを比較することができます。これらの統計は、トレンドの特定、システムの学習、潜在的な問題への対応に役立ちます。このようなツールは、有用な統計を提供するのに十分なデータを収集することを目的としているため、通常は精度を期待することはできないことに注意する価値があります。
API
上記の技術が最初は面倒に思えるとしても、落胆しないでください。システムに関するデータを探す最も簡単な方法は、既に使用しているツールのAPIです。多くのパフォーマンス監視、Web分析、アップタイム監視、IaaSツールは、システムのパフォーマンスと使用方法に関するデータを取得するためにクエリできるAPIを提供しています。
本番データからの学習
アラート
収集したデータは、誰も反応しなければ役に立ちません。そのため、何らかのアラートシステムをセットアップすることが重要です。本番環境で問題が発生した場合は、ユーザーへの影響を最小限に抑えるために、最初に知りたいと思うでしょう。ログデータまたは指標を監視し、アラートを送信する機能を備えたソフトウェアが必要です。これらのアラートは、メール、テキストメッセージ、またはチームが使用するチャットルームでの通知として配信される場合があります。次に、通知を受け取るためのルールである、アラートしきい値を設定する必要があります。求人応募の例では、学校にメールを送信できなかった場合(つまり、しきい値が1の場合)に通知を受け取ります。これは、この種のエラーはまれであり、発生した場合は真剣に受け止める必要があるためです。教師が応募を放棄する頻度を確認するには、他のデータに関連するアラートを設定する必要があります。1日の求人応募数が特定の数値を下回るか、現在のトレンドから著しく逸脱した場合、教師の応募を妨げている可能性があることを知らせるアラートを受け取ります。
アラートは、何かが間違っていることを知らせるだけではないことに注意することが重要です。優れたアラートは、何かが間違っている前にそれを知らせてくれます。システムについて学ぶほど、差し迫った問題を示す監視の設定が向上します。たとえば、特定のサーバーのメモリ使用率が64%を超えると、メモリリークが発生しており、すぐにリソースが不足することを示していることがわかっている場合があります。時間内に警告を受け取れば、メモリの問題に対処したり、バックアップサーバーをオンラインにすることができます。高度な設定では、自己修復メカニズムが含まれる場合もあります。
アラートにおける良好な信号対ノイズ比が不可欠です。チームが多数のアラートを受け取ったり、誤検知に関するアラートを受け取ったりすると、アラートはノイズになり、無視され、重要な問題が見過ごされる可能性があります。
ダッシュボード
ダッシュボードは、データをより簡単に消費できる一般的な方法です。これらは通常、グラフ(たとえば、すべてのサーバー全体のCPU使用率)または大きな個々の数値(たとえば、今日の求人応募数)のコレクションで構成されます。これらの視覚化のデータはさまざまなデータソースから取得できるため、使用しているダッシュボードツールでデータ処理や集約を行う必要がある場合があります。そうでない場合は、多くのツールが現在提供している組み込みダッシュボードを使用できます。チームの作業エリアの大きな画面にこれらの視覚化を表示すると、トレンドとステータスを一目で確認できます。チームがリモートで作業している場合は、ダッシュボードへのリンクを見つけやすくしてください。人間には、トレンドを発見し、異常を発見する優れた能力があるため、チームがデータを見ることに慣れている場合、複雑なデータクランチングアルゴリズムを維持することに投資しなくても、問題を見つけることができます。
組織が基本的なシステム統計をステータスページの形式でユーザーに公開することがますます一般的になっています。これにより、ユーザーは問題が発生したときに情報を得ることができ、問題に対処していることが保証されます。例としてGitHubのステータスページを参照するか、Tesで提供しているものを確認してください。
現実的なQAアプローチ
ほとんどの人がQAについて考えるとき、テストを考えますが、システムの品質を適切に把握するには、QAの他の側面を覚えることが重要です。システムについて学習し、最大の品質問題を分析することは、しばしば見過ごされている側面です。
テストは、既に知っているシナリオでのみ役立ちます。テストは、発生すると予想される欠陥を見つけるのに最適ですが、多くの本番環境での欠陥は予期せぬものです。ユーザー、ネットワーク、ブラウザ、デバイスは非常に多様で、非常に予測不可能です。テストでは、すべてのシナリオを網羅することはできません。テストは、システムが意図したとおりに動作することを確認する良い方法ですが、意図した動作が正しいかどうかを伝えることはできません。優れた本番環境の監視は、予期していなかったシナリオに関する貴重なフィードバックを提供し、システムの動作を適宜調整するのに役立ちます。QAは、システムの正しい動作を保護することと同じくらい、システムの正しい動作を学習することについてです。これは、しばしば見過ごされている側面です。
テストは価値を生み出す必要がある
テストは多くの組織に膨大な時間と費用を節約する貴重な実践ですが、テストにはコストがかかることを考慮する価値があります。一部のテストは保守と操作が容易ですが、他のテストははるかに多くの労力を必要とします。たとえば、UIまたはブラウザベースのテストは、不安定(多くの誤った失敗が発生する)、脆い(UIが進化するにつれて多くの保守が必要)、信頼性の低いダウンストリームシステムに依存することがよく知られています。特に、独自のハードウェアまたはソフトウェアに依存している組織では、パフォーマンステストは高価です。いくつかの機能が機能するかどうかを確認するUIテストを行う代わりに、重要な指標が特定のしきい値を下回らないように監視を行うことができます。シミュレートされた負荷の下で機能を配置するためのテストスイートを持つ代わりに、システムの平均応答時間を示す本番環境の指標を持つことができます。
チームは、これらのテストに費やした時間でサイトへの貴重な改善を継続的に行うことができ、システムに何か問題があると思われる場合は通知されます。何か問題が発生した場合は、調査して障害を修復できます。
本番QAプラクティスを採用する準備はできていますか?
簡潔に答えると、イエスです。ほとんどのチームは、本番環境で何が起こっているかにより多くの注意を払うことで、構築しているシステムについてより多くの洞察を得ることができ、基本的なダッシュボードとアラートを設定することの価値をすぐに理解するでしょう。
簡潔な回答の問題点は、本番環境でのQAには、この記事で説明されている手法に対して本番前の品質管理プラクティスの一部を交換できるという概念が含まれていることです。実際には、いくつかの有効な継続的デリバリープラクティスがなければ、この種のシフトをサポートすることは困難です。
従来の本番前QA技術を置き換える前に、テストの文化と関連するテストスキルを構築する必要があります。本番環境で見つけた問題を修正しようとするときは、他に何かを壊していないという確信を得るために、堅牢な自動テストセットを用意することが重要です。適切な種類のテストがないと、終わりのないWhac-A-Moleゲームをする危険があります。
本番データに依存して問題を特定するということは、これらの問題の修正は非常に時間制約があることを意味します。問題を解決したり、回避策を導入したら、その変更を迅速に本番環境に反映できる必要があります。そのためには、自動化されたデプロイメントを導入する必要があります。そうでなければ、状況をさらに悪化させる可能性のある手動エラーのリスクがあります。
適切なバランスを見つける
高価なテストを監視に置き換えることで、組織はより迅速に移動できますが、各組織は、この速度と、本番環境にリリースする前に物事が機能するかどうかを確実に確認する(またはできる限り確実に確認する)ことのバランスを見つける必要があります。このバランスは、対象のシステムに大きく依存します。たとえば、Facebookの開発チーム[1]は、本番環境で何かを壊した場合にそれを知らせる良好なフィードバックループがあり、修正を迅速にリリースできるため、一部のテストを省略できます。何か問題が発生し、誰かが写真を見ることができなかったり、友人の誕生日を逃したりしても、世界が終わるわけではありません。反対の極端な例として、医療機器をプログラミングする会社は、リスクが高く、フィードバックループが非常に遅いので、これらのデバイスを使用する前に、物事が機能することをできるだけ確実に確認する必要があります。ほとんどのシステムは、その中間点にあります。
どのシステムにも、回復が困難な問題があります。これらの場合は、本番環境でのミスを防ぐために、本番前テストにより多くの投資を行う必要があります。本番環境で発生するすべての問題には関連コストがあるため、どれくらい慎重である必要があるかを決定することが重要です。本番環境で問題が発生するまで待つことの利点は、実際に発生したため、修正する価値があることがわかっていることです。
一部の組織は既に本番環境ですべてのテストを行っていますが、システムの品質を理解するために問題または本番環境でのテストに完全に依存することは、アンチパターンです。本番環境でのQAはほんの一例である、適切なQAにはさまざまな品質管理プラクティスが必要であるという点を無視しています。プロセスにおいて「はい、それは良さそうです」と言えるポイントを探しているだけなら、システムを改善する方法についてほとんど何も学ぶことはありません。
本番前と本番環境の品質管理プラクティスの適切なバランスを見つけることで、システムの品質についてより現実的で包括的な理解を得ることができます。最も重要なことは、本番環境で何が起こっているかに注意深く注意することで多くのことを学ぶことができ、学んだことを使用してより優れた品質のものを作成できるということです。
脚注
1: Facebookは以前、「迅速に動いて、物事を壊す」というモットーを持っていました。これがすべての人にとって正しいアプローチではない理由については、このxkcd漫画を参照してください。
重要な改訂
2017年4月4日: 初版公開