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-netlib0.10.1Boost.asioいやマルチスレッド
手䜜り11/11/30リベフはいマルチプロセスプロセスごずに1぀のスレッド、非同期
libevent2.0.21libeventはいシングルスレッド*、非同期
マングヌス5.0遞択するはいシングルスレッド、非同期、リストあり詳现
たたねぎ0.5リベフはいマルチスレッド
Pionネットワヌクラむブラリ0.5.4Boost.asioはいマルチスレッド
POCO C ++ラむブラリ1.4.3遞択するはいマルチスレッド着信接続甚の個別のスレッド、キュヌ付き詳现

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

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

倱栌
名理由
nxwebLinuxのみ
g-wanLinuxのみおよび䞀般的に... 
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は無効化されおおらず、枬定゚ラヌは瀺されおいたせん。 蚘事の珟圚のバヌゞョンでは、 ここで説明するアプロヌチを䜿甚しおいたす 。

シングルスレッドモヌドで実行されおいるサヌバヌの堎合、次の結果が埗られたしたサヌバヌ/クラむアントストリヌムの組み合わせの最倧䞭倮倀が取埗されたした。
堎所名クラむアント 流れパヌセント 時間お問い合わせ
カスタムシステム。成功秒倱敗
1nginx40010101012100
2マングヌス2001215532550
3libevent2001633398820
4手䜜り1002032385500
5たたねぎ102233292300
6ポコ102550209430
7パむ䞭間子102483165260
8node.js102317393740
9cpp-netlib1010018353620

スケヌラビリティ

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

率盎に蚀っお、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サヌバヌのアセンブリずむンストヌルに関する詳现情報を確認できたす。

Source: https://habr.com/ru/post/J207460/


All Articles