プレステスト
プレステストの結果に影響を与える要因は?
- プレステスタからサーバーへのネットワーク遅延 (内部ネットワークまたはローカルでのテストを推奨)
- プレステスタからサーバーへの帯域幅 (内部ネットワークまたはローカルでのテストを推奨)
- HTTP keep-aliveが有効かどうか (有効にすることを推奨)
- 同時接続数が十分か (外部ネットワークでのテストでは、できるだけ多くの同時接続を実行することを推奨)
- サーバー側のプロセス数が合理的か (helloworldビジネスプロセス数はCPU数と同じにすることを推奨、データベースビジネスプロセス数はCPU数の4倍以上を推奨)
- ビジネス自身の性能 (例えば外部ネットワークデータベースを使用しているかどうか)
HTTP keep-aliveとは?
HTTP Keep-Aliveメカニズムは、単一のTCP接続で複数のHTTPリクエストとレスポンスを送信するための技術であり、性能テスト結果に大きな影響を与えます。keep-aliveを無効にすると、QPSが倍に減少する可能性があります。
現在のブラウザはデフォルトでkeep-aliveが有効になっており、あるHTTPアドレスにアクセスした後、接続を一時的に保持し閉じず、次回のリクエスト時にこの接続を再利用して性能を向上させます。
プレステスト時には、keep-aliveを有効にすることを推奨します。
また、keep-aliveを無効にしてプレステストを実行すると、クライアントのローカルポートがすぐにtimewait状態になり、総リクエスト数が一定の数量(一般的には約28,000)を超えると失敗するリクエストが発生します。
プレステスト時にHTTP keep-aliveを有効にする方法は?
abプログラムを使用してプレステストを行う場合は、-kオプションを追加する必要があります。例: ab -n100000 -c200 -k http://127.0.0.1:8787/
。
apipostでは、gzipヘッダーを返さなければkeep-aliveを有効にすることができません(apipostのバグ、以下を参照)。
その他のプレステストプログラムは一般的にデフォルトで有効になっています。
なぜ外部ネットワークでのプレステストでQPSが非常に低いのか?
外部ネットワークの遅延が大きいため、QPSが非常に低くなるのは正常な現象です。例えば、baiduのページをプレステストするとQPSは数十になる可能性があります。
内部ネットワークまたはローカルでテストを実行し、ネットワーク遅延の影響を排除することを推奨します。
外部ネットワークでプレステストを行う必要がある場合は、帯域幅が十分なことを保証しつつ、同時接続数を増やしてスループットを向上させることができます。
なぜnginxプロキシを通過すると性能が低下するのか?
nginxの実行にはシステムリソースが消費されます。同時に、nginxとwebmanの間の通信も一定のリソースを消費します。
しかし、システムのリソースは限定されており、webmanはすべてのシステムリソースを取得できないため、全体としてのシステム性能が低下することは正常な現象です。
nginxプロキシによる性能影響をできるだけ減少させるために、nginxのログを無効にする(access_log off;
)ことや、
nginxとwebmanの間でkeep-aliveを有効にすることを検討してください。参考:nginxプロキシ。
また、httpsはhttpに比べてより多くのリソースを消費します。なぜなら、httpsではSSL/TLSハンドシェイク、データの暗号化と復号化が必要で、パケットのサイズが増大し、より多くの帯域を占有するためです。これらは性能低下を引き起こします。
プレステストで短いリンク(HTTP keep-aliveを無効にする)を使用する場合、各リクエストで追加のSSL/TLSハンドシェイク通信が必要となり、性能が大幅に低下します。httpsのプレステストではHTTP keep-aliveを有効にすることを推奨します。
システムが性能の限界に達したかどうかをどうやって知るか?
一般的には、CPUが100%に達した時点でシステム性能が限界に達していることを示します。もしCPUに余裕があれば、限界には達していないため、適度に同時接続を増やしてQPSを向上させることができます。
もし同時接続を増やしてもQPSが上がらない場合は、webmanのプロセス数が不足している可能性がありますので、webmanプロセスを適切に増やしてください。それでも改善がない場合は、帯域幅が十分かどうかを検討してください。
なぜ私のプレステスト結果がwebman性能がgoのginフレームワークよりも低いのか?
techempowerのプレステストでは、webmanは純テキスト、データベースクエリ、データベース更新などすべての指標でginに対してほぼ倍の結果を示しています。
もしあなたの結果が異なる場合、webmanでORMを使用したことによる性能の大幅な損失が原因かもしれません。webman+ネイティブPDOとgin+ネイティブSQLを比較してみてください。
webmanでORMを使用するとどのくらい性能が損失するか?
以下は一組のプレステストデータです。
環境
サーバーは阿里云の4コア4G、ローカルのMySQLデータベース。10万件のレコードからランダムに1件のデータをjsonで返す、ローカルでのテスト。
ネイティブPDOを使用した場合
webman QPSは1.78万
laravelのDb::table()を使用した場合
webman QPSは0.94万に低下
laravelのModelを使用した場合
webman QPSは0.72万に低下
thinkORMの結果も類似しており、大きな違いはありません。
ヒント
ORMを使用すると性能が若干下降しますが、99%のビジネスにとって性能は既に限界を超えています。もしあなたがその1%に該当する場合は、CPUやサーバーを増加させることによって軽容易に解決できます。
私たちは開発効率、メンテナンスの容易さ、性能など複数の指標の間でバランスを見つけるべきであり、単に性能を追求するべきではありません。
なぜapipostを使用したプレステストでQPSが非常に低いのか?
apipostのプレステストモジュールにはバグがあり、サーバーがgzipヘッダーを返さないとkeep-aliveを維持できず、性能が大幅に低下します。
解決策として、返すデータを圧縮しgzipヘッダーを追加します。例:
<?php
namespace app\controller;
class IndexController
{
public function index()
{
return response(gzencode('hello webman'))->withHeader('Content-Encoding', 'gzip');
}
}
この他にも、apipostは特定の状況下で十分なプレッシャーを生成できないことがあります。同じ同時接続数の場合、apipostを使用するとabよりも約50%低いQPSを示します。
プレステストには、ab、wrk、または他の専門のプレステストソフトウェアを使用することを推奨します。
適切なプロセス数の設定
webmanはデフォルトでcpu*4のプロセス数を開放しています。実際には、ネットワークI/Oのないhelloworldビジネスのプレステストではプロセス数をCPUコア数と一致させるのが最適です。これにより、プロセス切り替えのオーバーヘッドを減少させることができます。
データベースやRedisなどのブロッキングI/Oビジネスの場合、プロセス数はCPUの3-8倍に設定できます。なぜなら、この場合はより多くのプロセスが必要で、ブロッキングI/Oに対するプロセス切り替えのオーバーヘッドは基本的に無視できるからです。
プレステストのいくつかの参考範囲
クラウドサーバー 4コア 4G 16プロセス ローカル/内部ネットワークテスト
- | keep-aliveを有効にした場合 | keep-aliveを無効にした場合 |
---|---|---|
hello world | 8-16万QPS | 1-3万QPS |
データベースの単一クエリ | 1-2万QPS | 1万QPS |
プレステストコマンドの例
ab
# 100000リクエスト 200同時接続 keep-aliveを有効にする
ab -n100000 -c200 -k http://127.0.0.1:8787/
# 100000リクエスト 200同時接続 keep-aliveを無効にする
ab -n100000 -c200 http://127.0.0.1:8787/
wrk
# 200 同時接続で10秒間のプレステスト keep-aliveを有効にする(デフォルト)
wrk -c 200 -d 10s http://example.com