負荷テストは、他のタイプのテストほど需要がなく、普及していません-そのようなテストを実行できるツールはそれほど多くありませんが、単純で便利なものは、一般的に片手で数えることができます。
パフォーマンステストに関しては、まず第一に、誰もがJMeterについて考えます。これは間違いなく、最も多くのプラグインを備えた最も有名なツールです。 JMeterは、Hello World以外のアプリケーションのテストが必要になるとすぐに、インターフェイスがわかりにくく、エントリのしきい値が高いため、JMeterが好きではありませんでした。
そして今、2つの異なるプロジェクトでのテストの成功に触発されて、私は比較的シンプルで便利なソフトウェア
-Locustに関する情報を共有することにしました
あまりにも面倒くさい人のために、私はビデオを録画しました:
これは何ですか
分散負荷をサポートするPythonコードを使用して負荷シナリオを指定できるオープンソースツールで、著者によると、一連のBattlefildゲームのBattlelogの負荷テストに使用されました(すぐに魅力的)
プロから:
- コピー&ペーストの例を含む簡単なドキュメント。 プログラミングスキルがほとんどなくても、テストを開始できます。
- 「ボンネットの下」では、 リクエストライブラリ(人々のためのHTTP)を使用します 。 そのドキュメントは、拡張チートシートおよび借方テストとして使用できます。
- Pythonサポート-言語が好き
- 前の段落では、テストを実行するためのクロスプラットフォームを提供します
- テスト結果を表示するための独自のFlask Webサーバー
マイナスのうち:
- キャプチャとリプレイなし-すべての手
- 前の段落の結果-あなたは脳が必要です。 Postmanと同様に、HTTPの仕組みを理解する必要があります。
- 最小限のプログラミングスキルが必要
- 線形負荷モデル-ファンを直ちに混乱させてガウスユーザーを生成します
テストプロセス
テストは複雑なタスクであり、計画、準備、実装の監視、結果の分析が必要です。 ストレステスト中に、可能であれば、結果に影響を与える可能性のあるすべてのデータを収集することが可能であり、必要です。
- サーバーハードウェア(CPU、RAM、ROM)
- サーバーソフトウェア(OS、サーバーバージョン、JAVA、.NETなど、データベースとデータ自体の量、サーバーとテストアプリケーションのログ)
- ネットワーク帯域幅
- プロキシサーバー、ロードバランサー、DDOS保護の存在
- 負荷テストデータ(ユーザー数、平均応答時間、1秒あたりのリクエスト数)
以下に説明する例は、ブラックボックス機能負荷テストとして分類できます。 テスト対象のアプリケーションについて何も知らなくても、ログにアクセスしなくても、パフォーマンスを測定できます。
始める前に
実際に負荷テストをテストするために、ローカルでシンプルなWebサーバー
https://github.com/typicode/json-serverをデプロイしました。 次の例のほとんどすべてを彼に提供します。 デプロイされたオンラインの例(
https://jsonplaceholder.typicode.com/)からサーバーのデータを取得しました
実行するには、nodeJSが必要です。
明らかなネタバレ :セキュリティテストと同様-禁止されないように、オンラインサービスをロードせずに、ローカルで猫のストレステストを行うことをお勧めします
開始するにはPythonも必要です。すべての例で、バージョン3.6とイナゴ自体(執筆時点ではバージョン0.9.0)を使用します。 コマンドでインストールできます
python -m pip install locustio
インストールの詳細は、公式ドキュメントに記載されています。
例の解析
次に、テストファイルが必要です。 それは非常にシンプルでわかりやすいので、ドキュメントから例を取り上げました。
from locust import HttpLocust, TaskSet def login(l): l.client.post("/login", {"username":"ellen_key", "password":"education"}) def logout(l): l.client.post("/logout", {"username":"ellen_key", "password":"education"}) def index(l): l.client.get("/") def profile(l): l.client.get("/profile") class UserBehavior(TaskSet): tasks = {index: 2, profile: 1} def on_start(self): login(self) def on_stop(self): logout(self) class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 5000 max_wait = 9000
それだけです! これでテストを開始できます。 始める前に例を見てみましょう。
インポートをスキップすると、最初の段階で、1行で構成される2つのほぼ同一のログインおよびログアウト機能が表示されます。
l.client-ロードを作成するHTTPセッションオブジェクト。 リクエストライブラリのメソッドとほぼ同じPOSTメソッドを使用します。 ほとんど-この例では、特定のサービスである完全なURLではなく、その一部のみを最初の引数として渡しているためです。
2番目の引数はデータを渡します-そして、自動的にjsonに変換されるPython辞書を使用するのが非常に便利であることに気づかずにはいられません
また、リクエストの結果は一切処理しません。成功した場合、結果(Cookieなど)はこのセッションで保存されます。 エラーが発生すると、記録されて負荷統計に追加されます。
リクエストを正しく記述したかどうかを知りたい場合は、次のようにいつでも確認できます。
import requests as r response=r.post(base_url+"/login",{"username":"ellen_key","password":"education"}) print(response.status_code)
base_url変数のみを追加しました。
この変数には、テスト対象のリソースの完全なアドレスが含まれている必要があります。
次のいくつかの関数は、負荷を作成するクエリです。 繰り返しますが、サーバーの応答を処理する必要はありません。結果はすぐに統計に反映されます。
次は
UserBehaviorクラスです(クラスの名前は任意です)。 名前が示すように、テスト対象のアプリケーションの真空下での球状ユーザーの動作を説明します。 ユーザーが呼び出すメソッドと呼び出しの頻度の辞書を
タスクプロパティに渡します。 現在、各ユーザーがどの関数とどの順序で呼び出すかがわからないという事実にもかかわらず、ユーザーはランダムに選択されますが、
インデックス関数は
プロファイル関数よりも平均2倍頻繁に呼び出されることを保証します。
動作に加えて、親クラスTaskSetでは、テストの前後に実行できる4つの機能を指定できます。 呼び出しの順序は次のとおりです。
- setup - UserBehavior(TaskSet)の開始時に1回呼び出されます -例にはありません
- on_start-起動時にロードの新しいユーザーごとに1回呼び出されます
- タスク -タスク自体の実行
- on_stop-テストの動作が終了したときに各ユーザーによって1回呼び出されます
- teardown - TaskSetの終了時に1回呼び出されます-例にもありません
ここで、ユーザーの行動を宣言する方法は2つあることに言及する価値があります。最初の方法は、上記の例ですでに示されています。 2番目の方法は、
UserBehaviorクラス内でメソッドを直接宣言することです。
from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): def on_start(self): self.client.post("/login", {"username":"ellen_key", "password":"education"}) def on_stop(self): self.client.post("/logout", {"username":"ellen_key", "password":"education"}) @task(2) def index(self): self.client.get("/") @task(1) def profile(self): self.client.get("/profile") class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 5000 max_wait = 9000
この例では、ユーザー関数と呼び出しの頻度は、
タスクアノテーションを使用して設定され
ます 。 機能的には、何も変わっていません。
この例の最後のクラスは
WebsiteUserです (クラスの名前は任意です)。 このクラスでは、ユーザー動作モデル
UserBehavior *** +、および各ユーザーによる個々のタスクの呼び出し間の最小および最大待機時間を定義します。 より明確にするために、ここで視覚化する方法を示します。
はじめに
パフォーマンスをテストするサーバーを実行します。
json-server --watch sample_server/db.json
また、サンプルファイルを変更して、サービスをテストし、ログインとログアウトを削除し、ユーザーの動作を設定できるようにします。
- 作業開始時にメインページを1回開く
- すべてのx2投稿のリストを取得する
- 最初の投稿x1にコメントを書く
from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): def on_start(self): self.client.get("/") @task(2) def posts(self): self.client.get("/posts") @task(1) def comment(self): data = { "postId": 1, "name": "my comment", "email": "test@user.habr", "body": "Author is cool. Some text. Hello world!" } self.client.post("/comments", data) class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 1000 max_wait = 2000
コマンドプロンプトで開始するには、コマンドを実行します
locust -f my_locust_file.py --host=http://localhost:3000
hostはテスト対象のリソースのアドレスです。 テストで示されたサービスのアドレスが追加されるのは彼にとってです。
テストにエラーがない場合、ロードサーバーが起動し、
http:// localhost:8089 /で利用可能になり
ます。ご覧のとおり、テスト対象のサーバーがここに示されています-テストファイルのサービスのアドレスが追加されるのはこのURLです。
また、ここでは、負荷に対するユーザー数と1秒あたりの成長を示すことができます。
ボタンで、ロードを開始します!
結果
一定時間後、テストを停止し、最初の結果を確認します。
- 予想どおり、開始時に作成された10人のユーザーはそれぞれメインページに移動しました
- 投稿のリストは平均して、コメントが書かれたよりも2倍頻繁に開かれました
- 各操作には平均および中央値の応答時間があります。1秒あたりの操作数は、今ではそれを取得して要件から予想される結果と比較しても、すでに有用なデータです
2番目のタブでは、負荷グラフをリアルタイムで見ることができます。 特定の負荷でサーバーがクラッシュしたり、その動作が変化した場合、これはすぐにグラフに表示されます。
3番目のタブで、エラーを確認できます-私の場合、これはクライアントエラーです。 ただし、サーバーが4XXまたは5XXエラーを返した場合、そのテキストはここに書き込まれます
テキストのコードでエラーが発生した場合、[例外]タブに分類されます。 これまでのところ、コードでprint()コマンドを使用することに関連する最も一般的なエラーがあります-これはログを記録する最良の方法ではありません:)
最後のタブでは、すべてのテスト結果をCSV形式でダウンロードできます
これらの結果は関連していますか? それを理解しましょう。 ほとんどの場合、パフォーマンス要件(記載されている場合)は次のように聞こえます。平均ページ読み込み時間(サーバー応答)は、Mユーザーの負荷でN秒未満でなければなりません。 ユーザーがすべきことを実際に指定していない。 そして、私はこれのためにイナゴが好きです-それはユーザーから期待される期待されるアクションをランダムに実行する特定の数のユーザーのアクティビティを作成します。
ベンチマークを実行する必要がある場合-異なる負荷でのシステムの動作を測定するために、動作のいくつかのクラスを作成し、異なる負荷でいくつかのテストを実行できます。
開始するにはこれで十分です。 この記事が気に入ったら、次の記事を書く予定です。
- 1つのステップの結果が以下で使用される複雑なテストシナリオ
- サーバー応答処理、として HTTP 200 OKが到着した場合でも間違っている可能性があります
- 遭遇する可能性のある明白な困難とその回避方法
- UIを使用しないテスト
- 分散負荷テスト