nodejsで渋滞の実例を実現します.

2613 ワード

node.jsの中で生まれ持ってきたシングルスレッドのプログラミング、コールバック関数の非同期スタイルは私達を時々喜び、時には憂えさせます.先にスレッドを言いますが、多くの人が会費でnode.jsのスレッドを解きました.どうやって高合併ができますか?この問題は本文の重点ではなく、ここまでです.少し明らかにして、node.jsのシングルスレッドはjavascriptエンジンだけを指しています.どうしてもjavascriptでマルチスレッドとブロッキングを実現することはできません.しかし、node.jsの他の態様については、IOなどマルチスレッドができないことを意味しない.現在node.jsが大量の要求を受け、これらの要求がIO密集型である場合、nodeは要求を受けるごとに、長い間かかっているIO操作に遭遇した場合、javascriptスレッドはここで待っているのではなく、制御を渡して、ResportスタックにIO操作を追加して完成した後に実行する操作です.(コールバックレベルが多すぎると、アクセス数が多すぎて、大量のコールバックチェーンがスタックに破裂する可能性があります.この期間に、node.jsは他の要求を処理できます.だから、node.jsにとっては、javascriptはシングルスレッドですが、毎回一つの要求しか処理できません.しかし、javascriptは一つの要求を処理する時間が短いです.(IO集約型アプリケーションにとっては)非同期処理が可能であれば、今回の要求はいずれも制御を解放し、node.jsが他の要求を処理できるようにします.これを同時に要求すると、IOは常に併発状態にあり、処理要求のスレッド数を減少させ、IOのスレッド数を増加させるために資源を節約します.通常は時間が長いIO密集型要求に対して、性能向上をもたらすことは間違いありません.
前�、くどくどとIO密集型を強調していますが、実はnode.jsの強みを強調しています.それに応じて、短板はCPU密集型の要求です.道理は簡単です.javascriptは同時にしません.他の要求を処理するには一つの要求が完了しなければなりません.一つは処理の時間が長くなるほど、他の要求が長くなります.同じ時間に一つだけお願いがあります.処理され、併発性能は低い.
ここで、私はちょっと説明したいのですが、node.jsはブロックされてはいけません.fs.readFile()を使って、fs.sync ReadFile()fs.readFileSync()の代わりに、非同期的に処理できる方法があります.
nodeの中は渋滞できません.nodeの外は渋滞できないという意味ではありません.前にfibersについて話しましたが、今はfibersの中で渋滞ができるように試してみます.httpを処理してください.
 
  
var Fiber = require('fibers');
var http = require("http");
Fiber(function () {
    var httpFiber = Fiber.current;
    var html = "";
    http.get("http://www.baidu.com", function (res) {
        var dataFiber = Fiber.current;
        res.on("data", function (data) {
            html += data;
        });
        res.on("end", function (data) {
            httpFiber.run();
        });
    });
    Fiber.yield();
    console.log(html);
}).run();
yield()、run()この2つの方法はまだ知らない学生は、自分で「fibers in node」を調べてください.
fibersの運行はnodeプロセスではないので、fibers内部での渋滞はnode全体の性能に影響しません.しかも実現も容易です.ブロックしたい時にfiber yieldを落とすだけです.運転を継続する必要があれば、run()を実行します.fiberを復元します.上記の例では、http.getが要求したときに現在のプログラムをブロックして、すべてのデータを受信したら、プログラムを復元したいです.そこで、http.getを呼び出して、Fiber.yield()を使います.このfiberを中断します.このreponseの傍受中に、endイベントがトリガされてデータ転送が完了したことを示したら、endのコールバック関数で、Fiber.current.run()を呼び出して、fiberを回復します.このように、後続のコードはhttp.get要求のデータを同期して取得します.
上記の例はただ一つの考えを提供しています.このようなアイデアを抽象的にパッケージ化すると、例えば、フィードバック関数をパラメータとして受け入れる非同期の方法をワンステップコリック化し、呼び出し後に中断し、プログラムのコードをコールバック関数としてハイジャックします.非同期データを取得した後、プログラムが所定のコールバック関数をトリガします.このようにすれば、基本的に異歩データを実現できます.この段はかなり乱れていますが、基本的にはfibers/futureの実現構想です.興味があれば、ソースコードを参考にしてください.