古いテストベンチの内部設計は、作業クラスターとは著しく異なりました。 サービスを起動するための初期化スクリプトは異なり、構成ファイルは場所と内容が異なりました。 サービス間の相互作用は、戦闘環境の機能を考慮せずに行われました。
定性的に新しいテスト結果を達成することができたソリューションのロジックを示します。
この記事は、 SQA Days-18での私の講演の続きです。
構成ファイル
私たちが最初に目にしたのは、テストベンチとバトルで異なる構成ファイルでした。 私たちの場合、これらは異なる場所のファイルでさえありました。 彼らのコンテンツについて話すと、それらは異なる人々によって異なる方法で書かれました。 これはどういう意味ですか? つまり、各パッケージは、バトルサーバーに/ var / lib / ...または/ usr / shared / ...にあるデフォルト設定ファイルをもたらしました。これらはテスト環境で便利な同じ設定です。 そして、それらを置き換える必要のあるものは、既に/ etc / package_nameの構成ファイルにありました。 システム管理者は、Jiraで対応するタスクを受け取ったときに設定を書き留めました。
この相互作用スキームは、戦闘中の構成ファイルが正しく構成されたことを保証しましたか? 絶対にありません。 戦闘環境で使用された設定ファイルはテストされていません! そのため、テスターと開発者は、「この設定を変更するよう先週依頼しました。 登録しましたか? 何が起こったかを見せてください。」
なぜこの状況が発生したのですか? なぜなら、テストベンチでは、以前はそれらを見ていたように、サービスは1つのサーバー上に存在するからです。 同じファイルシステム内。 そして、それらの一方の設定をファイル/ etc / default / jettyで変更する必要がある場合、もう一方の設定を何らかの方法で変更する必要があります。 これを行うために、さまざまなサービスを制御するための特別な初期化スクリプトがテストベンチで作成されました。 同じ場所で、自己記述のinitスクリプトで、非標準の場所にある構成ファイルが示されました。
競合を解決する
この競合を解決する方法は? ファイルシステムレベルでサービスを相互に分離する必要があると判断しました。 実際、戦闘では、各サービスは個別のサーバーまたは仮想マシン上でスピンします。
おそらくchrootは、ファイルシステムレベルでテストベンチ上のサービスを分離する問題を解決できるでしょう。 次に、各サービスには独自の/ etcフォルダーと独自の構成ファイルがあり、これらはバトルサーバー上の同じ場所にあります。 また、ログファイルは、戦闘と同じフォルダーにあります。 そして、このようなソリューションにより、本番環境と同じ構成ファイルをテストベンチで使用する方法の問題を解決することに近づきます。
ファイルシステムレベルでの分離は十分ですか?
古いテストベッドでは、すべてのサービスがそれぞれ独自のポートでローカルホストをリッスンしました。 そして、ローカルホストを介してお互いに話しました。 ただし、このサイトでは、各サービスはそのサーバー上に存在します。 また、各サービスは2つ以上のインスタンスで起動されます。 このようなソリューションは、まず、サービスの負荷分散と水平スケーラビリティのために必要です。 そして第二に、サービスの信頼性を確保するためです。 メンテナンスのためにサーバーの1つを停止する必要がある場合、他のサーバーが作業の一部を引き受けます。
したがって、1つのサーバーにサービスを提供する複数のサーバー間で要求を確実に分散するには、内部ロードバランサーが必要です。
システム管理者に有利ですか?!
そして、ここでタスクリストの別の項目を見ました。 バランサーの設定、これは私たちが以前にテストしたことがないものです! したがって、バランサーとして機能するnginx構成の作成に関連するリスクは、sysadminsに全面的にあります。 また、ライブサイト以外の場所で正しい動作を確認する機会がありませんでした。 そして時々、実験はあまりうまく終わりませんでした...
面白い。 システム管理者は、新しいテストベンチ作業スキームの実装から利益を得ることができることがわかりました。 おそらく彼らはプロジェクトに新しいスタンドを引き付けることができるでしょう。
バランサー
そして、新しいスタンドにはロードバランサーがあります。 次に、nginx構成のアップストリームにIPポートとサーバーポートを登録する必要があります。 各サービスに、実際に動作可能なサーバーを実際に割り当てる方が便利な場合があります。
そのため、ファイルシステムによるサーバーの分離に加えて、IP分離を追加しました。 さらに、rsyslogなどの補助サービスは、このサイトと同じ原理で動作できます。 おそらく、各サービスの設定ファイルがバトルと同じ場合のみです。
そして、これはタスクリストの3番目の項目です。 テストベンチとバトルサーバーの両方で、同じ構成ファイルと同じ内容の使用を保証する方法は?
同じ構成を達成する方法は?
各サービスを別々のサーバーで起動することを既に決定している場合、システム管理者が持っているデプロイスクリプトを使用できますか? そして彼らの助けを借りて、大規模なサイトと同じ構成ファイルをテストスタンドにレイアウトしますか? はい、できます。 支払いシステムまたはSMSメーリングからのパスワードは秘密にすべきであるという事実を考えると。
そして最後に、GitHubに計算スクリプトと設定を保存することが可能になります。秘密データはそこからクリアされるからです。 開発者とテスターの両方が、サイトに実装されている設定を共有するように要求してシステム管理者を訪問することを停止します。
GitHubの構成
設定ファイルでパスワードを非表示にするには、変数を使用します。 構成ファイル自体がAnsibleのJinja2テンプレートになっているためです。 それを使用して独自の計算システムを作成しました。 また、Ansibleを使用すると、2組の変数を持つことができます。 group_varsおよびhost_varsフォルダーの2つのペア。変数値が定義されています。 1つのセットはプレイブックフォルダーにあり、もう1つのセットはインベントリファイルフォルダーにあります。 そして、これらのセットの1つは常に他のセットよりも優先されます。
そのため、GitHubには、計算スクリプトと構成ファイルだけでなく、変数値のセット(秘密でない場合)も入れます。 これらは、アプリケーションのメモリ制限、スレッドまたはフォークされたプロセスの数、およびタイムアウトになります。 つまり バトルとテストベンチで異なる値。
秘密を守る
支払いシステムとSMSメールサービスのパスワード、データベースのパスワードなどの秘密の値は、プライベートシステム管理者リポジトリにあり、テスターはアクセスできません。
テストベンチでは、テスターはオペレーティングサービスからのプライベートな変数セットの代わりに、リポジトリの値を使用します。 そこでは、テストベッドに固有のパスワード、メモリ制限の値、スレッドとプロセスの数、またはテスト環境に固有のタイムアウトの両方を定義します。
スタンドごとに個別のサーバーは無駄です
上記から、テストベンチで実行するサービスの個々のサーバーが満たすべき要件を確認できます。
- ファイルシステムの分離。
- 別のIPアドレス。
- initを使用して、関連パッケージを実行します。
- Ansibleが動作するためのopensshd。
Linux、LXCコンテナーはこれらの要件を満たすことができます。 それらを使用する場合の追加の利点は、共有メモリを使用し、コンテナ内のアプリケーションが要求するときに共有メモリを割り当てることです。 また、仮想マシンとは異なり、大量のRAMをすぐには食いません。 これにより、メモリを節約できます。
ソリューションの利点は何ですか?
私たちの事実の結果として
- テストベンチの各サービスに擬似サーバーを割り当てました。
- バトルと同じ計算スクリプトと同じ設定ファイルを使用します。
- 内部バランサーのスタンド内のLinuxコンテナーで繰り返されます。
- deployスクリプトを使用して擬似サーバーにパッケージをロールするために、最初にGitブランチからパッケージを収集することを強制しました。
いくつかの結果を達成しました。
まず、コードブランチのテストから、ディストリビューションのパッケージのテストに移行しました。 これで、戦闘中にパッケージがクリーンなサーバーにインストールされ、動作するのに十分な権限を持つすべての必要なフォルダーを作成できるようになります。
次に、このサイトで使用されるのとまったく同じ構成ファイルのテストを開始しました。 そのため、構成の記述における人的要因を除外しました。これはサイトの崩壊につながる可能性があります。 スタンドと本番環境の違いを変数にしました。
第三に、バランサー構成のテストを開始しました。 したがって、タスクを準備する段階でも、戦闘で機能するインフラストラクチャ内でサービス間の相互作用を確認します。
そして第四に。 これで、各サービスの2つ以上のインスタンスを開始できます。 nginxでの再試行の動作をデバッグするだけでなく、新しいバージョンのリリース中にサイトがどのように動作するかをテストすることもできます。
サイトの新しいバージョンのリリースをシミュレートしているときに、自動テストを実行できるようになったと想像してください! また、1つのサーバーが既に新しいバージョンのソフトウェアで実行されているときにスタンドを安定して動作させるために、2番目のサーバーは更新のために停止され、3番目のサーバーは引き続き古いバージョンで応答します。 これは価値のある挑戦です!
結果
まとめると。 テストプロセスのリエンジニアリングとテストベンチのリファクタリングにより、優れた結果が得られました。 2年間、サイトの稼働率は99.9%を超えました。 数分で数える場合、これは優れた指標です。 1か月で、単純なサイトは43分未満になります。 同時に、ダウンタイムの定義を1秒あたり60,500エラーから20に3回厳しくしました。
また、HeadHunterであるオンラインビジネスの場合、稼働時間の改善は実際のお金の節約を意味します。 これに加えて、サイトの運用が以前より安定しているためにhh.ruに惹かれた顧客を追加します。 アップタイムはビジネスの重要な成功要因だと思いますか?
したがって、4つの簡単なステップ:
- スタンド上の個別のサーバーで各サービスを強調表示します。
- コードを持つブランチではなくパッケージをテストします。
- 操作およびテスト構成ファイルから計算スクリプトを使用します。
- バランサーを繰り返し、リリースプロセスをテストします( 非現実性は既にこれを行う方法を示しています)。
光の勝利は避けられません!