負荷テスト用のNode.jsネイティブアドオンの例を使用したスレッドとプロセス

1年ほど前に、組み込みの機能(クラスターおよびネットモジュール)を使用してNode.jsで負荷テストツールを作成しようとすることについてメモを書きました。 コメントは、RPS分析と他のベンチマークとの比較の必要性を正しく指摘しました。 比較の結果、データ交換のコストが非常に高いため、マルチプロセスサービスのパフォーマンスがマルチスレッドサービスと同等になることはないという自然な結論に達しました(後で例を挙げて検証します)



プロセスまたはスレッド?



一見、大きな違いはありません。これは並列リクエストを保証します。違いはスレッドの共有メモリにのみあり、プロセスを作成するプロセスは少し高価です。 ただし、すべてのプロセスを事前に作成し、タスクを単純に転送できます。 しかし、今は通信チャネルが必要です。 プロセス間通信の方法を見てみましょう。



信号



システムとプロセス間の高速で汎用的な(ほぼすべてのOSでサポートされている)通信方法。 問題は例外的な剛性であり、JSONを送信するために作成されたものではありません。



ソケット



これは、クラスターがNodeに実装される方法です。 process.sendメソッドは、TCPを介して別のプロセスにデータを送信します。 ソケットとはどういう意味ですか? これは、各呼び出しの新しい記述子、大量のI / OおよびアイドルCPUを意味します。



さらにいくつかの方法がありますが、それらはすべてクロスプラットフォームではないか、I / Oにも依存しています。

100個のプロセスを作成するときのシステムの状態を見てみましょう。







そして100スレッド:







明らかに、CPUはこれらのプリミティブプロセス間の通信の維持にのみ関係します(誰もが1つの要求を実行する必要があります。そうでない場合、V8はそれらを同期イベントループに入れます)。 CPU使用率がクラッシュし、各リクエストに時間がかかります(メモリが不足してページファイルがなくなった場合、神は禁止します)



しかし、ノードはシングルスレッドです。どうすればよいですか?







マルチスレッドを使用して、C ++でネイティブアドオンを作成します。 Nan、Node-gyp、POSIXスレッド、およびその結果、 アドオンはabに似たものなりました-並行性が入力に到達し、テスト結果が出力になります。 abとは異なり、jsのすべての機能を使用して結果を分析できます。



[ { time: 80, body: '<!doctype html><html itemscope=...', headers: 'HTTP/1.1 200 OK\r\nDate: Mon, 28 Dec 2015 10:37:35 GMT\r\nConnection: close\r\n\r\n' }, .... ]
      
      





追加のヘッダー、POSTペイロードがサポートされています。POSIXであるため、残念ながらLinux / Macのみです。

必要に応じて、ヘッダーのみを読み取ることができます。通常はこれで十分です。保存できます

もう少し処理時間がかかります。



その結果、nnbのパフォーマンスはabと同等であり、異なるマシンおよびネットワークで最大3000 RPSを実現しました。



なぜこれが必要なのですか?



JMeter、Tsng、他の多くの有料および無料のベンチマークがありますが、それらの多くが開発者の兵器庫に根付かない理由は、機能が過負荷であり、その結果、まだ十分な柔軟性がありません。 nnbに基づいて、特定の目的のために独自のツールを作成するか、最も人気のある言語の1つで必要なことだけを行う10行のスクリプトを作成できます。

たとえば、デフォルトの設定で起動し、負荷が増加したときにGoogle RPSで何が起こるかをリアルタイムで見ることができるストレス (スポイラー:なし)は、ブラウザーやUNIXマシンで実行できます。







ここで、横軸の送信されたリクエストの数は、縦軸にサーバーの応答時間(ミリ秒)です。 2番目のグラフでは、1秒あたりのリクエスト。 結局、あなたは減速を見ることができます、それはおそらく私を切断し始めたのはホスティング会社でした。



残念ながら、利用可能なマシンでは、5000 RPSを超えることはまだできません。 通常、すべてはネットワークの制限に依存します。 同時に、CPUとメモリはほとんどロードされていません。 ところで、ストレスは、Node.jsクラスターとnnbを介したマルチスレッドの両方をサポートします。 ulimit -u(ユーザーが起動するプロセスの最大数)とulimit -n(記述子の最大数)を設定することで、これとそれを試すことができます。



記事がお役に立てば幸いです。 このトピックに関心のある皆さん、そしてもちろん、今後のトピックにご協力いただければ幸いです!



All Articles