バランサーの戦い

Battle of the Balancersは、WebSocketをサポートするバランサー/プロキシの負荷テストです。 これらのテクノロジーは、インフラストラクチャのスケーリングに不可欠です。



次のテクノロジーがテストされました。



-http -proxy 、バージョン:0.10.0

-HAProxy、バージョン:1.5-dev18(開発リリース)

-制御テスト用の基本的な「エコーサーバー」。



腰痛に疑いがありました 。 除外された理由は簡単です-http-proxyに基づいて構築されています。 現時点では、彼らはプロジェクトのフォークを使用しています。このプロジェクトでは、パフォーマンスに関連するパッチはまったくありません。



テストのために、3つの異なる接続されていないサーバーが使用されました



1.プロキシ、512Mb、Ubuntuサーバー。 すべてのプロキシがこのサーバーにインストールされました。 画像:sdc:jpc:ubuntu-12.04:2.4.0

2. WebSocketエコーサーバーが回転していたNode.jsを備えた512MBの「スマートマシン」WebSocketサーバー。 サーバーはNode.jsで記述されており、クラスターモジュールを使用して複数のカーネルで実行されます。 画像:sdc:sdc:nodejs:1.4.0

3.トール、512MB、Node.js上のもう1つの「スマートマシン」。前の仕様と同様の仕様です。 このサーバーから必要な負荷を生成しました。 Thorは、当社が開発したWebSocket負荷生成ツールです。 このアプリケーションはオープンソースで配布されており、 http://github.com/observing/thorで入手できます



プロキシ設定



プロキシサーバーは、Ubuntu 12.04を備えた「クリーン」サーバーでした。 すべての依存関係を構成およびインストールするために、次の手順が実行されました。 最新バージョンで作業していることを確認するには、次を実行します。



apt-get upgrade
      
      





次の依存関係がシステムにインストールされました。

-githubリポジトリにアクセスするgit

-ソースからプロキシをコンパイルするために不可欠なビルド、ほとんどのプロキシはWebSocketまたはHTTPSのサポートを最近取得したばかりです

-HTTPSをサポートするにはlibssl-devが必要です

-スタッドにはlibev-devが必要です。これはすごいです



 apt-get install git build-essential libssl-dev libev-dev
      
      





Node.js
Node.jsはhttp-proxyに必要です。 http-proxyはNode.jsの最新バージョンを使用しますが、これらのテストはすべての依存関係の互換性を確保するためにバージョン0.8.19で実行されました。 Node.jsはgithubで複製されています。



 git clone git://github.com/joyent/node.git cd node git checkout v0.8.19 ./configure make make install
      
      





このプロジェクトの依存関係をインストールできるように、バイナリnpmがインストールされます。 このリポジトリとhttp-proxyのルートでnpm installを実行すると、すべての依存関係が自動的にインストールされます。



Nginx
Nginxはすでに普及しているサーバーです。 さまざまなサーバーバックエンドへのプロキシをサポートしていますが、WebSocketはサポートしていません。 少し前までは、Nginxブランチの開発に追加されました。 したがって、最新の開発バージョンをインストールし、ソースからコンパイルしました。

この記事のテストと執筆以来、nginx 1.4.0がリリースされており、WebSocketがサポートされています。 したがって、この記事を読んでいて本番環境に展開する予定がある場合は、バージョン1.4.0を使用することをお勧めします。 開発バージョンの代わりに。



 wget http://nginx.org/download/nginx-1.3.15.tar.gz tar xzvf nginx-1.3.15.tar.gz cd nginx-1.3.15 ./configure --with-http_spdy_module --with-http_ssl_module \ --pid-path=/var/run/nginx.pid --conf-path=/etc/nginx/nginx.conf \ --sbin-path=/usr/local/sbin --http-log-path=/var/log/nginx/access.log \ --error-log-path=/var/log/nginx/error.log --without-http_rewrite_module
      
      





これらのオプションからわかるように、SSL、SPDYをオンにし、他のいくつかの設定を使用しました。 最終的に、この一般的な構成が出てきました。



 Configuration summary + PCRE library is not used + using system OpenSSL library + md5: using OpenSSL library + sha1: using OpenSSL library + using system zlib library nginx path prefix: "/usr/local/nginx" nginx binary file: "/usr/local/sbin" nginx configuration prefix: "/etc/nginx" nginx configuration file: "/etc/nginx/nginx.conf" nginx pid file: "/var/run/nginx.pid" nginx error log file: "/var/log/nginx/error.log" nginx http access log file: "/var/log/nginx/access.log" nginx http client request body temporary files: "client_body_temp" nginx http proxy temporary files: "proxy_temp" nginx http fastcgi temporary files: "fastcgi_temp" nginx http uwsgi temporary files: "uwsgi_temp" nginx http scgi temporary files: "scgi_temp"
      
      





その後:



 make make install
      
      





HAProxy
HAProxyは、以前はtcpモードでWebSocketをプロキシでき、現在はhttpモードでもプロキシできました。 HAProxyはHTTPS終了のサポートも受けました。 そのため、開発ブランチをインストールする必要があります。



 wget http://haproxy.1wt.eu/download/1.5/src/devel/haproxy-1.5-dev18.tar.gz tar xzvf haproxy-1.5-dev18.tar.gz cd haproxy-1.5-dev18 make TARGET=linux26 USE_OPENSSL=1 make install
      
      





スタッド
HAProxyにはSSL終了機能がありますが、スタッドは通常、HAProxyの前のSSL終了に使用されます。 そして、これも検証したいと思います。



 git clone git://github.com/bumptech/stud.git cd stud make make install
      
      





すべてがインストールされたので、構成ファイルを構成する必要があります。 Nginxの場合、nginx.confをこのリポジトリのルートから/etc/nginx/nginx.confにコピーできます。 他のプロキシはその場で構成できます。



カーネル調整



すべてのプロキシをインストールした後、ソケットの調整が必要です。 この情報をインターネットから取得しました。



 vim /etc/sysctl.conf
      
      





そして、次の値が設定されます。



 # General gigabit tuning: net.core.somaxconn = 16384 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.ipv4.tcp_syncookies = 1 # this gives the kernel more memory for tcp # which you need with many (100k+) open socket connections net.ipv4.tcp_mem = 50576 64768 98152 net.core.netdev_max_backlog = 2500
      
      







ベンチマーク



2つの異なるテストが実行されます。

1. SSLなしでテストプロキシサーバーを読み込みます。 この場合、WebSocketプロキシのパフォーマンスのみをテストします。

2.テストプロキシサーバーにSSLをロードします。 安全でないWebSocketを使用しないでください。 ブラウザの接続が非常に悪いです。 ただし、ここではSSL終了プロセス中にプロキシサーバーに余分な負荷が追加されます。

2つのテストに加えて、異なる数の化合物を試します。

-2k

-5k

-10k

また、同じ結果を得るために:

-20k

-3万

各テストの前に、すべてのWebSocketサーバーがリセットされ、プロキシが再初期化されます。 Thorは、すべてのプロキシにX個の接続と100の同時接続をロードします。 確立された接続ごとに、1つのUTF-8メッセージが送受信されます。 メッセージを受信した後、接続は閉じられます。



打ち上げ



スタッド


 stud --config stud.conf
      
      





HAProxy


 haproxy -f ./haproxy.cfg
      
      





Nginx


 nginx
      
      





HTTPプロキシ


 FLAVOR=http node http-proxy.js
      
      





WebSocketServer


 FLAVOR=http node index.js
      
      





結果



http-proxyはその名の通り、リクエストをプロキシし、十分高速に処理します。 しかし、以来 Node.jsに基づいており、多くのメモリを消費します。 最も単純なノードプロセスでも、12 MB以上のメモリが必要です。 1万件のクエリの場合、約70 MBのメモリが必要でした。 コントロールテストと比較して、HTTPプロキシは5秒以上かかりました。 Node.jsがSSLを介して失われているため、予想どおりHTTPSは最も遅い結果を示しました。 そして、これは、重い負荷の下で、メインイベントループを完全に停止するという事実は言うまでもありません。

メモリ使用量を大幅に削減するhttp-proxyのプルリクエストがあります。 手動でパッチを適用した結果、食べた記憶が半分になりました。 それでも、パッチの後でも、Nginxと比較してより多くのメモリを使用します。これは、純粋なCで後者を記述することで簡単に説明できます。

私はNginxに大きな期待を持っていましたが、それは私を失敗させませんでした。 彼は10 MBを超えるメモリを使用せず、非常に迅速に解決しました。 Nginxを初めてテストしたとき、ひどいパフォーマンスを示しました。 NodeはNginxよりもSSLでさらに速い結果を示しましたが、何らかのエラーがあるはずだと感じました。Nginxの設定は間違っているはずです。 友人からのいくつかのヒントの後、設定の1行を実際に変更しました-暗号化設定が正しくありませんでした。 openssl s_client -connect serverを使用した少しの設定と確認:すべてが修正されました(現在、デフォルトでは本当に高速なRC4暗号化が使用されています)。

次に、HAProxyがありました。これは、NGINXと同じパフォーマンスを示しましたが、必要なメモリはより少なく(7 MB)でした。 最大の違いは、HTTPSでのテスト時でした。非常に遅く、Nginxに近いものでもありませんでした。 これが修正されることを願っています、なぜなら これまでのところ、開発ブランチのみをテストしました。 次に、Nginxと同じ間違いをしました 。暗号化が正しく構成されていません 。これはHackerNewsで正しく認識されました 。 HTTPSのテストに加えて、示されているパフォーマンスをテストするために、その前にスタッドを設置しました。



結論



http-proxyは非常に柔軟なプロキシであり、簡単に拡張および追加できます。 実稼働環境で使用する場合は、SSL終了のためにその前でスタッドを実行することをお勧めします。

nginxとhaproxyは非常に近い結果を示しましたが、そのうちの1つがより高速またはより良いと言うことは困難です。 しかし、管理の観点からそれらを見ると、スタッドおよびhaproxyよりも1つのnginxを使用して展開および操作する方が簡単です。



HTTP
プロキシ 接続 握手(中) レイテンシー(中) 合計
HTTPプロキシ 10k 293ミリ秒 44ミリ秒 30168ミリ秒
nginx 10k 252ミリ秒 16ミリ秒 28433ミリ秒
ハプロキシ 10k 209ミリ秒 18ミリ秒 26974ミリ秒
制御 10k 189ミリ秒 16ミリ秒 25310ミリ秒
勝者 :NginxとHAProxyは非常に高速で、結果は近いです。



Https
プロキシ 接続 握手(中) レイテンシー(中) 合計
HTTPプロキシ 10k 679ミリ秒 62ミリ秒 68670ミリ秒
nginx 10k 470ミリ秒 30ミリ秒 50 180ミリ秒
ハプロキシ 10k 464ミリ秒 25ミリ秒 50058ミリ秒
haproxy +スタッド 10k 492ミリ秒 42ミリ秒 52403ミリ秒
制御 10k 703ミリ秒 65ミリ秒 71500ミリ秒
勝者 :NginxとHAProxyは非常に高速で、結果は近いです。



すべてのテスト結果は、 https//github.com/observing/balancerbattle/tree/master/resultsで入手できます



寄稿



すべての構成はリポジトリ内にあります。サーバーのパフォーマンスが向上するかどうかを確認できれば幸いです。



All Articles