nodejsでWebフロントエンドサーバーのいくつか経験をします.

7811 ワード

先日NCZが新しい文章を発表しました.Node.js and the new web front-end(翻訳文)は、node.jsを用いてWebフロントエンドサーバとしての様々な利点を説明しました.NCZは記事の中でサーバーモデルのセットを紹介しました.
このモデルは、従来のバックグラウンドサーバーの前に、node.js実装のフロンティアServer層を追加しました.このアーキテクチャの最大の利点は、フロントエンドの開発者の依存分離であり、バックエンドの開発者は、データがページ間でどのように伝達されるか、ユーザーデータの取得はAjaxを通じて行われるか、それともページを更新するかなどの先端開発に関わる側面に関心を持たなくてもいいです.The front-end and back-end now have a perfect split of concerns amongst the enginers who are work on those parts.The front-end has expand the server the Noder.js UI layer noxtres therereress.私は社内でこのようなアーキテクチャを試しました.ここではNode.jsのWebフロントエンドサーバーの経験を共有しています.
バックグラウンドサーバとのインタラクション
ユーザの一度の要求では、しばしば、異なる複数のバックグラウンドインターフェースを要求する必要がある.node.jsの非同期特性のため、何度もHTTP要求を書いて、フィードバックを処理するのはとてもつらいことです.
var request = require('request');

exports.index = function (req, res) {
    request('API_A', function (err, response, body) {
        if (err) {
            // ...
        }
        request('API_B', function (err, response, body) {
            if (err) {
                // ...
            }

            request('API_C', function (err, response, body) {
                if (err) {
                    // ...
                }

                // ...
            });
        });
    });
};
このような状況は[async]ライブラリを通してこの問題をうまく解決できます.[async]はツールパッケージであり、様々な関数を提供してnode.jsの非同期フィードバック処理を簡略化します.
var request = require('request');
var async = require('async');

exports.index = function (req, res) {
    async.map(['API_A', 'API_B', 'API_C', /* ... */], request, function (err, results) {
        if (err) {
            // ...
        }

        var resultA = results[0];
        var resultB = results[1];
        var resultC = results[2];
        // ...
    });
};
async.mapを通じて、並列要求データを簡単に実現できます.シリアル要求データが必要であれば、async.Series関数を使用することができます.この他に、async.mapLimitを使用してnode.jsの同時接続数を制限することもできます.
一般的なAPIデータの取得
いくつかのAPIデータは、ほぼすべてのページで使用されます.例えば、現在のユーザの個人情報などです.このようなデータに対しては、middleware方式でcontrollerに伝えることができます.
var request = require('request');
var async = require('async');

function userdata (req, res, next) {
    request('GET_USER_API', function (err, response, body) {
        if (err) {
            next(err);
            return;
        }

        req.user = JSON.parse(body);
        next();
    });
}

app.get('/pageA', userdata, pageAController);
app.get('/pageB', userdata, pageBController);
app.get('/pageC', userdata, pageCController);
Cookieエージェント
APIインターフェースがCookieを検証する必要がある場合、node.jsはAPI要求を送信する際、ユーザのCookie情報をバックグラウンドサーバに送信する必要がある.同様に、バックグラウンドAPIインターフェースが、ユーザCookie、例えばAPIにログインするように修正された場合、node.jsは、ユーザCookieを設定する要求をユーザに転送する必要がある.これはcookie Request方法を実現する必要があります.
var request = require('request');
var cookieRequest = function (userRequest, userResponse, url, callback) {
    var options = {
        url: url,
        headers: {}
    };
    options.headers.Cookie = userRequest.header('Cookie'); //      Cookie         

    request(options, function (error, response, body) {
        userResponse.setHeader('Cookie', response.headers.cookie);
        callback.apply(null, arguments);
    });
};
核融合最適化
node.jsのシングルプロセス特性のため、一つのnode.jsのインスタンスだけを起動すると、マルチコアCPUの性能を十分に発揮できません.したがって、node.jsはclusterモジュールを提供してこの問題を解決します.clusterは複数のサーバープロセスを管理し、マルチコアCPUの性能を十分に発揮する.使い方は簡単です.新しい起動スクリプトを作成し、clusterモジュールを呼び出してサービスを開始すればいいです.node.js公式のAPI文書は簡単な例をあげました.
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {
  // Workers can share any TCP connection
  // In this case its a HTTP server
  http.createServer(function(req, res) {
    res.writeHead(200);
    res.end("hello world
"
); }).listen(8000); }
パフォーマンス
古いWebサーバーはtomcat+javaのアーキテクチャを使って、node.jsでフロントエンド層全体を書き換えた後、サービス全体の性能が向上しました.今のプロジェクトは個人の娯楽ですので、あまり専門的な性能テストもしませんでした.abで適当に圧力をかけました.私のiMac(2.7 G i 5、12 G)では約20%の性能が上がりました.これはnode.js HTTPモジュールの高性能及び同時要求APIと無関係ではない.結語はプロジェクト規模の拡大に伴い、Webフロントエンドサーバとバックエンドサーバの分離は避けられない傾向にある.node.jsは先端開発者に対してより友好的なWebフロントエンドサーバーの方案を提供しています.この方案は前後のエンド開発者をお互いの苦手な分野から救い出し、コミュニケーションコストを低減し、開発効率を向上させるために非常に大きな助けがあります.