2016-04-25 7 views
0

私はnodejsで新しく、いくつかの実験をしています。私はそれらから得たもの(そして私が間違っていることを願っています!)は、nodejsが同じリソースに対する複数の同時リクエストを順番に処理することができなかったことです。同じリソースのnodejsマルチスレッド

次のコード(私は、次の例ではExpressのフレームワークを使用して)考えてみましょう:コードの一部は、上記の2つのエンドポイントを公開し

var express = require('express'); 
var app = express(); 

app.get('/otherURL', function (req, res) { 
res.send('otherURL!'); 
}); 

app.get('/slowfasturl', function (req, res) 
{ 

    var test = Math.round(Math.random()); 

    if(test == "0") 
    { 
     var i; 
     setTimeout 
     (
      function() 
      { 
       res.send('slow!'); 

      }, 10000 
     ); 

    } 
    else 
    { 
     res.send('fast!'); 
    } 

}); 

app.listen(3000, function() { 
     console.log('app listening on port 3000!'); 
    }); 

シナリオ1: "!速い" のすぐと返事を単純なテキスト

または

シナリオ2: "!遅い" と10秒後に返信シンプルなテキスト

私のテスト: 同時に、slowfasturlのURLで複数のクロムの呼び出しウィンドウを開きました。最初のリクエストが「シナリオ2」に該当することがわかりました。 (シナリオ1)に落ちている(そして「ゆっくり!」を返す)か「シナリオ2」(そして「速く!」)という事実を明白に他の要求はクロームの他のウィンドウと続いて発砲した。要求は、最初の1つ(「シナリオ2」に該当するもの)が完了しない限り、少なくともブロックされます。

どのようにこの現象について説明しますか?同じリソースに対して行われた要求はすべて順番に処理されますか?

「シナリオ2」のリクエストが応答を待っている間に、2番目のリクエストが別のリソース(たとえば、上記で説明したotherurl URL)に行われた場合、別の動作が発生します。この場合、第2の要求は最初の1

ダヴィデ私が覚えている限りでは

答えて

0

ありがとうを待たずに、すぐに完了し、要求はブラウザ側がブロックされています。

お使いのブラウザはこれらの並列要求を防止していますが、サーバーは処理できます。異なるブラウザで試してみるか、カールを使うとうまくいくはずです。

+0

@AsTeR様、もう一度チェックしました。たとえば、複数のブラウザを使用している場合(たとえば、Chromeで1つのリクエストとIEで1つのリクエスト)、リクエストは並行して管理されているようです。しかし、setTimeoutを(同期的に実行される)Date.now()をチェックするループに置き換えると、要求は順番に管理されます!次のことができますか?処理がコールバック関数に委譲されるまで、nodejsリスナーによって要求が順番に管理されます(これはsetTimeoutの場合です)。 –

+0

setTimeoutは、将来処理する予定を追加していますループ、あなたのスレッドはそのループでブロックされます。 JavaScriptで何かをブロックしてはいけません。気づいているようにフリーズします。私はあなたがここに新しい人であることに気付きました。「歓迎!」私の答えが正しければ、隣の緑色のチックをチェックすることができます。 – AsTeR

0
  1. あなたが観察する動作は、ブラウザが行うすべてのシーケンシングによってのみ説明できます。ノードは順番にリクエストを処理するのではなく、イベント駆動型モデルで動作します。libuv framework

  2. 私はブラウザ以外のクライアントでテストケースを実行し、リクエストが互いに影響しないことを確認しました。

さらなる証拠を得るために、私は次のことをお勧め:

  1. 問題の範囲を分離します。 express(http抽象化)を削除し、http(ベースhttp impl)、またはnet(TCP)モジュールを使用します。
  2. ブラウザ以外のクライアントを使用します。私はab(あなたがLinuxの場合) - 特にWebサーバーのパフォーマンス測定用のApacheベンチマークツールを提案します。 私は

ab -t 60 -c 100 http://127.0.0.1:3000/slowfasturl

  • を使用100の同時クライアントのために、60秒のデータを収集。
    1. Math.randomをカウンタに置き換え、巨大なタイムアウトと小さなタイムアウトを切り替えることで、より決定的になります。
    2. 結果を確認すると、遅い応答と速い応答の速度とパターンが表示されます。

希望します。

+0

これは最も完全であるため、これを正しいものとしてマークします。 –

+0

親愛なる@Gireesh Punathil様、もう一度チェックしました:例えば、私は異なるブラウザを使用しています(例えば、ChromeとIEで1つのリクエスト)並行して管理する。しかし、setTimeoutを(同期的に実行される)Date.now()をチェックするループに置き換えると、要求は順番に管理されます!次のように言えますか?:処理がコールバック関数に委譲されるまで、要求はnodejsリスナーによって順番に管理されます(これはsetTimeoutのケースです)。 –

+0

Davide、実験ベースの推論集合モデルを見てうれしく思います。あなたの推論は正解です。この動作をより包括的に解釈すると、次のようになります。リクエストは、外部(ペリフェラル)依存なくマシン内で実行可能である限り、そのような依存性を伴う操作に遭遇するまで、待ち時間。ノード内の実行時系列を記述するイベントの詳細なシーケンスは、ここで見つけることができます:http://stackoverflow.com/questions/10680601/nodejs-event-loop –

0

Davide:この質問には詳細が必要なので、スペースの制約があるコメントではなく、別の答えとして追加する必要があります。

あなたは問題として、現在のノードモデルを示唆している場合:

従来の言語(およびランタイム)は、コードが順番に実行される原因となりました。スレッドはこれをスケールするために使用されましたが、次のような副作用があります。 i)共有データアクセスが必要なシーケンシング、ii)I/O操作ブロック。ノードは、これらの問題に対処するために、3つのエンティティ libuv(マルチプレクサ)、v8(エグゼキュータ)、およびノー​​ド(オーケストレータ)の間の慎重な統合の結果です。このモデルは、Webとクラウドの配備でパフォーマンスとスケーラビリティを向上させます。したがって、このアプローチに問題はありません。

待ち時間があるノードでストレスの多いCPUバウンド操作を管理するためのさらなる改善が必要な場合は、マルチコアを活用し、CPU負荷の高いワークロードを共有するスレッドを増やすことが適切です。

これが役に立ちます。

関連する問題