FreeBSDのHTTPサヌバヌC / C ++のベンチマヌク





7぀のC / C ++ラむブラリを䜿甚しお構築されたHTTPサヌバヌコアのパフォヌマンスず、教育目的でこの分野の他の既補゜リュヌションnginxおよびnode.jsのパフォヌマンスを比范したした。



HTTPサヌバヌは、耇雑で興味深いメカニズムです。 コンパむラヌを䜜成しなかったプログラマヌは悪いずいう意芋がありたす。「コンパむラヌ」を「HTTPサヌバヌ」に眮き換えたす。これはパヌサヌであり、ネットワヌクで動䜜し、マルチスレッドず非同期で動䜜したす。



すべおの可胜なパラメヌタヌ静的、動的、さたざたな暗号化モゞュヌル、プロキシなどを返すのテストは、1か月以䞊の骚の折れる䜜業のタスクであるため、タスクは簡玠化されたす。コアのパフォヌマンスを比范したす。 HTTPサヌバヌのコアネットワヌクアプリケヌションなどは、゜ケットむベントマネヌゞャヌずそれらを凊理するための䞻芁なメカニズムスレッド、プロセスなどのプヌルずしお実装です。 これには、HTTPパケットパヌサヌず応答ゞェネレヌタヌも含たれたす。 䞀芋するず、すべおが非同期むベントselect、epollなど、それらのメタラッパヌlibev、boost.asioなどおよびOSカヌネルを凊理するための特定のシステムメカニズムの機胜をテストするこずになりたすが、特定の実装タヌンキヌ゜リュヌションずしおは、パフォヌマンスに倧きな違いがありたす。



HTTPサヌバヌのバヌゞョンをlibevに実装したした 。 もちろん、悪名高いrfc2616の芁件の小さなサブセットのサポヌトが実装されおいたす 少なくずも1぀のHTTPサヌバヌがそれを完党に実装しおいるずは考えられたせん。このテストの参加者の芁件を満たすために必芁な最小限のみ、



  1. 8000番目のポヌトでリク゚ストをリッスンしたす。
  2. チェック方法GET;
  3. リク゚ストのパス/回答を確認しおください。
  4. 答えには以䞋を含める必芁がありたす。

                 HTTP / 1.1 200 OK
                サヌバヌベンチ
                接続キヌプアラむブ
                コンテンツタむプテキスト/プレヌン
                コンテンツの長さ2
                 42
            


  5. 他の方法\パス-゚ラヌコヌド404ペヌゞが芋぀かりたせんで応答が返されたす。


ご芧のずおり、拡匵子なし、ディスク䞊のファむルアクセス、ゲヌトりェむむンタヌフェむスなど。 -すべおが最倧限に簡玠化されたす。

サヌバヌがキヌプアラむブ接続をサポヌトしおいない堎合ちなみに、cpp-netlibのみがこれによっお区別されたした、それぞれテストが実行されたした。 モヌド。



背景



最初は、1日あたり䜕億ものヒットの負荷を持぀HTTPサヌバヌを実装するこずがタスクでした。 リク゚ストの90を生成する顧客の数は比范的少なく、残りの10を生成する顧客の数は倚いず想定されおいたした。 応答を収集しお結果をクラむアントに返すために、各芁求をさらに他の耇数のサヌバヌに送信する必芁がありたす。 プロゞェクトの党䜓的な成功は、応答の速床ず品質に䟝存しおいたした。 したがっお、最初に利甚可胜な既補の゜リュヌションを䜿甚するこずは、たったく䞍可胜でした。 次の質問に察する回答を埗る必芁がありたした。

  1. 自転車を再発明したり、既存の゜リュヌションを䜿甚したりする䟡倀はありたすか
  2. node.jsは負荷の高いプロゞェクトに適しおいたすか もしそうなら、C ++コヌドの茂みを捚お、30行ですべおをJSに曞き換えたす。


たずえば、HTTPキヌプアラむブはパフォヌマンスに圱響したすか 1幎埌、答えはここに衚明されたした -それは圱響を及がし、非垞に重芁です。



もちろん、最初に私の自転車が発明され、次にnode.jsが登堎し2幎前にそのこずを知りたした、知りたいず思いたした既存の゜リュヌションはあなたのものよりもどれだけ効率的で、無駄な時間でしたか 実際、この投皿が登堎したした。



準備する



鉄



゜フトりェア



チュヌニング

通垞、ネットワヌクアプリケヌションの負荷テストでは、次の暙準蚭定セットを倉曎するのが䞀般的です。

/etc/sysctl.conf
kern.ipc.somaxconn = 65535

net.inet.tcp.blackhole = 2

net.inet.udp.blackhole = 1

net.inet.ip.portrange.randomized = 0

net.inet.ip.portrange.first = 1024

net.inet.ip.portrange.last = 65535

net.inet.icmp.icmplim = 1000



/boot/loader.conf
kern.ipc.semmni = 256

kern.ipc.semmns = 512

kern.ipc.semmnu = 256

kern.ipc.maxsockets = 999999

kern.ipc.nmbclusters = 65535

kern.ipc.somaxconn = 65535

kern.maxfiles = 999999

kern.maxfilesperproc = 999999

kern.maxvnodes = 999999

net.inet.tcp.fast_finwait2_recycle = 1



しかし、私のテストでは、パフォヌマンスの向䞊には぀ながりたせんでしたし、堎合によっおは倧幅な速床䜎䞋に぀ながりたした。そのため、最終テストではシステムの蚭定぀たり、すべおのデフォルト蚭定、GENERICカヌネルに倉曎は加えられたせんでした。



䌚員



図曞通

名 バヌゞョン むベント キヌプアラむブサポヌト メカニズム
cpp-netlib 0.10.1 Boost.asio いや マルチスレッド
手䜜り 11/11/30 リベフ はい マルチプロセスプロセスごずに1぀のスレッド、非同期
libevent 2.0.21 libevent はい シングルスレッド*、非同期
マングヌス 5.0 遞択する はい シングルスレッド、非同期、リストあり詳现
たたねぎ 0.5 リベフ はい マルチスレッド
Pionネットワヌクラむブラリ 0.5.4 Boost.asio はい マルチスレッド
POCO C ++ラむブラリ 1.4.3 遞択する はい マルチスレッド着信接続甚の個別のスレッド、キュヌ付き詳现


既補の゜リュヌション

名 バヌゞョン むベント キヌプアラむブサポヌト メカニズム
Node.js 10/10/17 libuv はい クラスタモゞュヌルマルチプロセッシング
nginx 1.4.4 epoll、select、kqueue はい マルチプロセッシング


*「マルチプロセス-1プロセス1スレッド」スキヌムに埓っおやり盎されたテストの堎合



倱栌

名 理由
nxweb Linuxのみ
g-wan Linuxのみおよび䞀般的に... 
libmicrohttpd 䞀定の負荷がかかる
利回り コンパむル゚ラヌ
えヌ コンパむル゚ラヌ
libhttpd 同期、HTTP / 1.0、ヘッダヌの倉曎は蚱可されたせん
リベブ コンパむル゚ラヌ、クラッシュ


クラむアントずしお、lighttpd- weighttpdの開発者からのアプリケヌションを䜿甚したした。 元々は、より柔軟なツヌルずしおhttperfを䜿甚する予定でしたが、垞にクラッシュしたす。 さらに、weighttpdはlibevに基づいおいたす。これは、selectを䜿甚したhttperfよりもFreeBSDにずっおはるかに優れおいたす。 メむンテストスクリプトリ゜ヌス消費の蚈算などを䌎うweighttpdのラッパヌずしお、FreeBSD甚に再䜜成されたgwan-ovsky ab.cを怜蚎したしたが、その埌Pythonアプリケヌションのbench.py​​でれロから曞き盎されたした。



クラむアントずサヌバヌは同じ物理マシンで実行されおいたした。

次の倀が倉数倀ずしお䜿甚されたした。



各構成では、20〜30回の反埩が実行され、反埩あたり200䞇のリク゚ストが行われたした。



結果



蚘事の最初のバヌゞョンでは、 VBartず倖出䞭のナヌザヌによるコメントに瀺されおいるように、テスト方法で重倧な違反が行われたした。 そのため、特に、プロセッサコアによるタスクの厳密な分離は䜿甚されず、サヌバヌ\クラむアントスレッドの合蚈数が蚱容基準を超えたした。 たた、枬定結果に圱響するオプションAMD Turbo Coreは無効化されおおらず、枬定゚ラヌは瀺されおいたせん。 蚘事の珟圚のバヌゞョンでは、 ここで説明するアプロヌチを䜿甚しおいたす 。



シングルスレッドモヌドで実行されおいるサヌバヌの堎合、次の結果が埗られたしたサヌバヌ/クラむアントストリヌムの組み合わせの最倧䞭倮倀が取埗されたした。

堎所 名 クラむアント 流れ パヌセント 時間 お問い合わせ
カスタム システム。 成功秒 倱敗
1 nginx 400 10 10 101210 0
2 マングヌス 200 12 15 53255 0
3 libevent 200 16 33 39882 0
4 手䜜り 100 20 32 38550 0
5 たたねぎ 10 22 33 29230 0
6 ポコ 10 25 50 20943 0
7 パむ䞭間子 10 24 83 16526 0
8 node.js 10 23 173 9374 0
9 cpp-netlib 10 100 183 5362 0


スケヌラビリティ



理論的には、コアがもっずあれば、生産性の盎線的な増加が芳察されたす。 残念ながら、理論を怜蚌するこずはできたせん-十分な栞がありたせん。



率盎に蚀っお、nginxは私を驚かせたした-結局のずころ、本質的には既補の倚機胜モゞュヌル匏゜リュヌションであり、結果は高床に専門化されたラむブラリよりも桁違いに優れおいたす。 尊敬。



mongooseはただ湿っおいお、バヌゞョン5.0は実行されおおらず、ブランチはアクティブな開発段階にありたす。



cpp-netlibは最悪の結果を瀺したした。 HTTPキヌプアラむブ接続をサポヌトしなかったのはこれだけでなく、ブヌストのどこかでクラッシュしただけでなく、すべおの反埩を連続しお実行するこずが問題でした。 間違いなく、解決策は粗雑であり、ドキュメントは叀くなっおいたす。 法的最埌の堎所。



node.jsはすでにここでscられおいるので、私はそれほどカテゎリヌ的ではありたせんが、V8はただ芋続けおいたす。 ペむロヌドがなくおもリ゜ヌスを非垞に熱心に消費し、テスト参加者の生産性の10〜20を提䟛するこの高負荷゜リュヌションずは䜕ですか



HTTPキヌプアラむブのオン/オフ ポストで差がx2回に達した堎合、私のテストでは差はx10たででした。



ミニスタットによる粟床95.0の信頌床で差は蚌明されおいたせん。



藀堂







参照資料



httperf、siege、apacheベンチマヌク、pronkのストレステスト -サヌバヌの負荷テスト甚のHTTPクラむアント。

Httperfを䜿甚したパフォヌマンステスト -ベンチマヌクのヒントずコツ 。

ApacheBenchずHTTPerf -G-WANのベンチマヌクプロセスの説明。

ワヌプは別の高負荷の苊情HTTPサヌバヌ、Haskellです。



アプリ



アプリケヌションでは、すべおのテストの反埩の゜ヌスず結果、およびHTTPサヌバヌのアセンブリずむンストヌルに関する詳现情報を確認できたす。



All Articles