分散システムの複雑性はコードの中ではなく、サービスや機能の間にある。テストには問題の発見と価値提供のバランスという意味があるのだ – Sarah Wells氏はEuropean Testing Conferenceで、このように説明した。テスタはしばしば、システム動作の最大の理解者である。システムのどこが悪いのかについて優れた仮説を持ち、それを極めて短期間に検証することができるのは彼らなのだ。
基調講演の中で氏は、複雑な分散システムになることで何が変わるのかを説明した。システムがモノリスである場合、ある処理をどのコードが行っているのかを特定するのは難しいかも知れないが、システムを通過する要求の流れを決めるのは簡単であり、通信は主にプロセス内で行われる。しかし分散システムでは、複雑性はシステム内からシステム間に移っているのだ、とWells氏は主張する。
マイクロサービスのコードは単純だが、ルーティングは複雑であり、http上あるいはキュー経由で行われる。事態をさらに難しくするのは、Wells氏いわく、ある要求が一時的なエラーで失敗しても、数秒後に繰り返すと成功することが少なくない、ということだ。バックオフとリトライを実装することは合理的ではあるが、それによって、要求に対する応答の間に何が起こったかを正確に把握することが難しくなっている、と氏は指摘する。
Wells氏はリスクベースのアプローチを採用して,実際に重要な問題にテスト作業を集中する方法を提案する。問題が発生したことを素早く見つけて,それを素早く修正する必要がある,そのためには問題を解決するための可観測性を備えたシステムを開発しなければならない,と氏は言う。
複雑な分散システムをテストするためには,問題の早期発見と,可能な限り早い価値提供という,2つのバランスを取る必要がある,とWells氏は指摘する。いくつかの問題は,運用に至るまで見つからないものと受け止めた方がよいだろう,その上で,できる限り早い発見と修正のために最適化するべきだ,というのが氏の意見だ。
InfoQではEuropean Testing Conference 2019を取材するとともに,基調講演を終えたSarah Wells氏に,複雑な分散システムのテストについて話を聞いた。
InfoQ: 複雑な分散システムをテストする上で,どのようなアドバイスがありますか?
Sarah Wells: テストを始めて分かったことは,システムの完全なレプリカをローカルに立ち上げようとしてもうまくいかない,ということです。これは開発者にとっても,テスタにとっても同じです。運用システムのレプリカの作成にいくら時間を費やしても,結局はどうにもならないのです。
これにはシステムの複雑さが関係しています。特定の変更に対して想定される影響範囲を評価できなければ,回帰テストに多くの時間が必要になります。これがボトルネックになると同時に,問題の発見を不可能にしていることが分かりました。
多くのことがそうであるように,問題はコミュニケーションにあります。開発者が自分の行ったことを理解できるように説明してくれれば,テスト担当者は変更された中から,最もリスクの高い可能性のある部分をピンポイントで突き止めることができます。
最も有効なのは,継続的デリバリとマイクロサービスです。マイクロサービスには極めて明確な境界があるので,変更は小さく,自己完結的なものになります。また,(書籍"Accelerate"などの)調査結果から,小規模な変更を頻繁にリリース可能な企業では,変更に対する障害発生率が極めて低いことが分かっています。
システム間の契約を確立することは有用だと思いますが,それを誤解するリスクよりも,契約テストをメンテナンスするためのコストが大きいのではないかと思っています – これはおそらく,システム内よりもチーム間のバウンダリで行うべきものでしょう。
InfoQ: 監視やログによってテストをどのようにサポートできるのでしょう?あるいは置き換えも可能なのでしょうか?
Wells: 分散システムでは,問題の多くはリリースされたコード自体とはほとんど関係がありません。コードが実行される環境,あるいはサービス間の依存関係に関わっていることが多いのです。つまり,ひとつの変更が,予期しない別の部分でエラーを発生させるのです。そのサービスは,同じチームが所有するものではないかも知れません。自分たちのAPIを呼び出していることさえ知らない場合もあるのです。
ですから,変更を運用環境に移行した後には,問題の早期発見とロールバックが重要になります。
これを実現するには,重要なビジネス機能を常時テストする人為的監視(synthetic monitoring)のようなものや,実際のイベントが完全に成功したことをチェックするビジネス機能レベルの監視が必要になります。私たちの仕事はコンテンツの公開ですので,各リージョンの関連するすべてのデータストアが正しく更新されていることをチェックして,問題があれば警告するようにしています。
私たちはこれを,もっと下位の環境でも行っています。不安定な受け入れテストの代用として,このテストを実施しているのです。それまでは,変更時のセットアップ変更が大変でしたが,これらのアーキテクチャで状況は大きく変わります。
問題点を解決可能にするためには、可観測性を備えたシステムを開発する必要があります。
それは例えば、すべてのログをひとつのログストアに集約した上で、クエリを簡単に実行できるように構造化しておく必要がある、というようなことです。最終的にはログをサンプリングすることになる(要求が複数のサービスを通過するので、モノリスで経験したよりも数桁多いログが収集される可能性があります)かも知れませんが、その場合でも、特定のログがすべて、確実に格納されていることが必要なはずですし、ユニークなトランザクションIDを使ってそれらを関連付けられた方がよいと思うでしょう。
メトリクスも取り込みたいと思うかも知れませんが、これは過剰になりがちです。本当に必要なのは、ユーザコール数や要求率、エラー率(おそらくは要求率の割合として)、要求期間(REDメトリクスとも呼ばれます)といった、サービスのトップレベルでのメトリックスのはずなのです。
InfoQ: 問題が発生した場合、テスタはどのように貢献できるのでしょう、また、どのような価値を提供できるのでしょうか?
Wells: 私の経験から、テスタはプロダクトオーナと並んで、システムの挙動を最もよく理解できていることが少なくありません。(さらには、テスタが最終的にプロダクトオーナになることも多いのです)。
これには2つの意味があります。まずひとつは、問題に対してテスタの立てる仮説が優れていることです。
もうひとつは、その仮説を極めて早く検証できることです – これはテスタが、APIコールやWebサイトのフローをすでに知っているからです。
問題が発生する前にも、彼らは多くの価値を提供することができます。カオスエンジニアリングは調査を中心とするものですから、テスタが関わるのはごく自然なことだと思います – それ以外に考えられますか?あるいは、このキーが期限切れになったら?複雑な分散システムでは、このような仮説と回復力のテストは非常に重要で、価値の高いものなのです。