23

TornadowebNginxは現在人気のある Web サーバーであり、多くのベンチマークでは、特定の状況下で Apache よりも優れたパフォーマンスを発揮することが示されています。だから私の質問は:

「epoll」は、それらを非常に高速にする最も重要な理由ですか? 優れたソケット サーバーを書きたい場合、そこから何を学べるでしょうか。

4

2 に答える 2

67

ソケットサーバーの作成を検討している場合、出発点としては、数年前のDanKegelのC10k記事が適しています。

http://www.kegel.com/c10k.html

また、Beejのネットワークプログラミングガイドは非常に便利であることがわかりました。

http://beej.us/guide/bgnet/

最後に、優れたリファレンスが必要な場合は、W。RichardStevenset。によるUNIXネットワークプログラミングがあります。al .:

http://www.amazon.com/Unix-Network-Programming-Sockets-Networking/dp/0131411551/ref=dp_ob_title_bk

とにかく、あなたの質問に答えるために、ApacheとNginxの主な違いは、ApacheがブロッキングI / Oでクライアントごとに1つのスレッドを使用するのに対し、Nginxは非ブロッキングI/Oでシングルスレッドであるということです。Apacheのワーカープールは、プロセスの開始と破棄のオーバーヘッドを削減しますが、複数のクライアントにサービスを提供する場合でも、CPUを複数のスレッド間で切り替えます。一方、Nginxは、すべてのリクエストを1つのスレッドで処理します。1つのリクエストがネットワークリクエスト(たとえば、バックエンド)を作成する必要がある場合、Nginxはバックエンドリクエストにコールバックをアタッチしてから、別のアクティブなクライアントリクエストを処理します。実際には、これはイベントループ(epoll、、、kqueueまたはselect)そして、報告するものがあるファイル記述子を要求します。ファイル記述子の1つが読み取りまたは書き込みの準備ができるまで何もすることがないため、メインイベントループでのシステムコールは実際にはブロッキング操作であることに注意してください。

これが、NginxとTornadoが多数の同時クライアントに効率的にサービスを提供する主な理由です。プロセスは1つだけ(つまりRAMを節約)、スレッドは1つだけ(つまりコンテキストスイッチからCPUを節約)です。epollに関しては、selectのより効率的なバージョンです。開いているファイル記述子(ソケット)がN個ある場合は、O(N)時間ではなくO(1)で読み取る準備ができているものを選択できます。実際、オプションを指定してコンパイルすると、Nginxはepollの代わりにselectを使用できますが--with-select_module、Apacheよりも効率的であると思います。私はApacheの内部に精通していませんが、簡単なgrepは、selectとepollを使用していることを示しています。おそらく、サーバーが複数のポート/インターフェイスをリッスンしている場合、または単一のクライアントに対して同時にバックエンド要求を行う場合です。

ちなみに、私は基本的なソケットサーバーを作成しようとしてこのようなことを始め、Nginxがいかに効率的であるかを理解したいと思いました。Nginxのソースコードを調べて、上記でリンクしたガイドや書籍を読んだ後、自分のサーバーよりもNginxモジュールを作成する方が簡単であることがわかりました。このようにして、今や半伝説的なNginxモジュール開発ガイドが誕生しました。

http://www.evanmiller.org/nginx-modules-guide.html

(警告:ガイドはNginx 0.5-0.6に対して作成されており、APIが変更されている可能性があります。)HTTPで何かをしている場合は、愚かなクライアントに対処するための厄介な詳細がすべて解決されているので、Nginxを試してみてください。たとえば、私が楽しみのために書いた小さなソケットサーバーは、Safariを除くすべてのクライアントでうまく機能しましたが、その理由はわかりませんでした。他のプロトコルの場合でも、Nginxが正しい方法かもしれません。イベントはプロトコルからかなり抽象化されているため、IMAPだけでなくHTTPもプロキシできます。Nginxコードベースは非常によく整理されており、非常によく書かれていますが、1つの例外があります。プロトコルパーサーを手動でローリングすることになると、私はその先導に従いません。代わりに、パーサジェネレータを使用してください。Nginxでパーサージェネレーター(Ragel)を使用する方法について、ここにいくつか書いています。

http://www.evanmiller.org/nginx-modules-guide-advanced.html#parsing

これらはすべて、おそらくあなたが望んでいたよりも多くの情報でしたが、うまくいけば、いくつかの情報が役立つでしょう。

于 2010-05-24T18:37:22.147 に答える
5

はいといいえ。どちらも epoll を使用していますが、技術的には、両方ともリクエストを処理するためにイベント ループを使用しています。イベント ループとは何か、およびそれらがどのように使用されるかについての詳細は、wikipediaで見つけることができます。

実装については、 libevent ( geventで使用され、一般に tornado よりも高速で安定しています) またはlibevを確認してください。

于 2010-04-12T20:26:43.207 に答える