セルジオが正しいです。あなたのアプリは、現時点では、おそらく従来のApache/Passengerモデルの方が優れています。特にRubyのようなシングルスレッドプラットフォームでは、DB、キャッシュサーバー、その他のHTTPリクエストなど何でもブロックすることはできません。
これは、非同期(イベント)プログラミングを難しくするものです。通常、同期ディスクのI/OまたはDNS解決の形で、ブロックするのは簡単です。 nodejのようなノンブロッキング(イベント)されたフレームワークは、(ほとんど)コールバック(DBクエリを含む)を使用して処理されるフレームワーク関数呼び出しをブロックしないことに注意しています。
あなたはシングルスレッドノン・ブロッキングサーバーの心を見ればこれは視覚化しやすいかもしれません:
イベントループと呼ばれるあなたが上記を参照
while(wait_on_sockets(/* list<socket> */ &$sockets, /* event */ &$what, $timeout)) {
foreach($socketsThatHaveActivity as $fd in $sockets) {
if($what == READ) { // There is data availabe to read from this socket
$data = readFromSocket($fd);
processDataQuicklyWithoutBlocking($data);
}
elseif ($what == WRITE && $data = dataToWrite($fd)) { // This socket is ready to be written to (if we have any data)
writeToSocket($fd, $data);
}
}
}
。 wait_on_sockets
は通常、select、poll、epoll、kqueueなどのシステムコールの形でOSによって提供されます。 processDataQuicklyWithoutBlockingに時間がかかりすぎると、OSによって保持されているアプリケーションのネットワークバッファ(新しい要求や着信データなど)が最終的にいっぱいになり、$ socketsThatHaveActivityが十分に速く処理されないため、新しい接続を拒否し、 。これはスレッド化されたサーバー(典型的なApacheのインストール)とは異なり、各接続は別々のスレッド/プロセスを使って提供されるため、到着するとすぐに受信データがアプリケーションに読み込まれ、送信データは遅滞なく送信されます。
nodejのようなノンブロッキングフレームワークは、DBクエリを(例えば)監視するソケットのリスト($ソケット)にDBサーバーのソケット接続を追加することですしばらくして、あなたの(唯一の)スレッドはそのソケットでブロックされません。むしろ彼らは、コールバック提供:あなたが上見ることができるように
$db.query("...sql...", function($result) { ..handle result ..});
を、db.queryは絶対に無い全くDBサーバー上でブロックするとすぐに戻ります。また、これは、プログラミング言語自体は(新しいC#のような)非同期機能をサポートしていない限り、あなたが頻繁に、このようなコードを記述しなければならないことを意味:
$db.query("...sql...", function($result) { $httpResponse.write($result); $connection.close(); });
あなたは多くのプロセスを持っている場合は、決して、常にブロックルールが多少緩和することができますイベントループ(通常はノードクラスタを実行する方法)を実行するか、スレッドプールを使用してイベントループを維持します(javaのjetty、nettyなど、C/C++で独自に記述できます)。 1つのスレッドが何かでブロックされている間も、他のスレッドは引き続きイベントループを実行できます。しかし、十分に重い負荷の下では、これらは実行することができません。したがって、イベントが発生したサーバーでは決してブロックしないでください。
このように、イベントが発生したサーバーは一般的に、さまざまな問題を解決しようとします。開いている接続の数が非常に多いことがあります。彼らが優秀なところでは、軽い計算(例えば、彗星サーバ、memcached、ワニス、nginx、squidなどのプロキシのようなキャッシュ)を使ってバイトをプッシュするだけです。彼らのスケーラビリティは向上しますが、応答時間は一般的に増加する傾向があります(接続のスレッド全体を予約するよりも優れているわけではありません)。もちろん、同時接続数と同じ数のスレッドを実行することは、経済的に/計算上では実現できない可能性があります。
あなたの問題に戻って - Nginxを接続管理(イベントベース)に優れているので、あなたはまだNginxを守っておくことをお勧めします - 一般にHTTPキープアライブやSSLなどを処理することを意味します。 FastCGIを使ってあなたのRailsアプリケーションに、ワーカーを実行する必要がありますが、完全にイベントが発生するようにアプリケーションを書き直す必要はありません。また、Nginxに静的なコンテンツを提供させるべきです.Railsの作業者がNginxが通常より良くできることに縛られることはありません。このアプローチは一般にApache/Passengerよりもはるかに優れています。特にトラフィックの多いWebサイトを使用している場合は特にそうです。
あなたのアプリケーション全体をイベントとして書くことができれば、素晴らしいですが、Rubyでどのように簡単か難しいかはわかりません。
ワウ..詳細な応答Tejasのおかげで。だから、私がネットから読んだベンチマークは、まったく異なるアプリケーションジャンルのものですか? Thin自身のサイトは、薄型のサンプルアプリケーションとしてレールアプリを提供しています。 http://code.macournoyer.com/thin/。私は乗客を薄いものに置き換えることができたと思っていましたが、すべてが大変なことになりました。 –
どこでもブロックしない限り、それらのベンチマークを再作成できるはずです。 – tejas