サンドボックスでのクラスタリングとコード実行を使用したNode.jsでのMVCアプリケーションの構築

こんにちは、Habrの読者の皆さん! この記事は、私がJSの世界を開いたばかりの初心者を対象としています。 Node.jsでサーバーを調査および設計する過程で、開発者は常にアプリケーションを再起動する必要に直面しています。 そして、何人かの人々がプロジェクトに取り組んでいる場合、私たちはかなり難しい仕事をします。



タスクは、サーバーを上げて、たとえばhttp://127.0.0.1/habrおよびhttp://127.0.0.1/habrahabrなどのいくつかのURLを処理することです。 サーバーは例外を処理する必要があり、プロジェクトは高負荷向けに設計されています。



この記事の目的は、チームワークに便利で初心者にとって理解しやすいホットスワップアプリケーションを作成する方法を理解することです。



最初にすることは、Node.jsでサーバーを上げることです。



var http = require('http'); var file = new static.Server('.'); http.createServer(function(req, res) { file.serve(req, res); }).listen(80);
      
      





問題は、サーバーが1つのシステムプロセスでのみ実行されることです。 コードを少し修正し、クラスタリングを追加します。このため、標準のクラスターモジュールを使用します。



 const cluster = require('cluster'); const http = require('http'); const domain = require('domain'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { for (var i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', function(worker, code, signal){ console.log('worker ' + worker.process.pid +' died'); cluster.fork(); }); cluster.on('online', function(worker) { console.log('Worker ' + worker.process.pid + ' is online'); }); } else { http.createServer(function(req, res){ //   var d = domain.create(); //   ,   500     d.on('error', function(err) { res.statusCode = 500; res.setHeader('content-type', 'text/plain'); res.end('!\n'+ err.stack); }); //   ,       d.add(req); d.add(res); //       d.run(function () { var route_json = require('./application/route.json'); if( route_json[req.url] !== undefined){//    console.log(route_json[req.url].controller); }else{ url = urlapi.parse(decodeURI(req.url), true);// url url_arr = url.pathname.slice(1).split('/');// url   } res.end('hello world'); }); }).listen(3031).on('connection', function(socket) { socket.setNoDelay(); //   . }); }
      
      





メインサーバーのコードを把握しました。非同期例外ハンドラーを備えたサーバーがあり、URLをクラスタリングして処理しています。 MVCパラダイムを使用しているため、codeigniterを標準として採用しています。 ファイル構造は次のとおりです。



画像



構造の説明:





コントローラーのコード処理が必要です。 この問題を解決するには、いくつかの方法があります。





ドキュメントから、vmはコンテキストで実行されることがわかります。新しいコンテキストで実行することも、現在のコンテキストで実行することもできます。 最も正しい解決策は、新しいコンテキストでコードを実行することです。



完全なサンプルコード:



 const cluster = require('cluster'); const http = require('http'); const domain = require('domain'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { for (var i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', function(worker, code, signal){ console.log('worker ' + worker.process.pid +' died'); cluster.fork(); }); cluster.on('online', function(worker) { console.log('Worker ' + worker.process.pid + ' is online'); }); } else { http.createServer(function(req, res){ //   var d = domain.create(); //   ,   500     d.on('error', function(err) { res.statusCode = 500; res.setHeader('content-type', 'text/plain'); res.end('!\n'+ err.stack); }); //   ,       d.add(req); d.add(res); //       d.run(function () { var route_json = require('./application/route.json'); var fs = require('fs');//     if( route_json[req.url] !== undefined){//    var path = './application/controller/'+route_json[req.url].controller+'.js'; }else{ var urlapi = require('url');//    url var url = urlapi.parse(decodeURI(req.url), true);// url var url_arr = url.pathname.slice(1).split('/');// url   var path = './application/controller/'+url_arr[0]+'.js'; } //     fs.readFile(path, 'utf8', function(err, code) { var vm = require('vm'); var timestart = parseInt(new Date().getTime()); var pid = cluster.worker.process.pid; var context = { // --     pid:pid, res:res, req:req, timestart:timestart, require: require, console: console }; var vmContext = vm.createContext(context); var script = vm.Script(code); script.runInNewContext(vmContext); }); }); }).listen(3031).on('connection', function(socket) { socket.setNoDelay(); //   . }); }
      
      





コントローラーコードの例:



 res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Headers', 'origin, content-type, accept'); res.setHeader("Cache-Control", "no-cache, must-revalidate"); res.writeHead(200, {"Content-Type": "text/plain"}); res.write('CONTROLLER RUN'); res.end();
      
      





したがって、メインアプリケーションを再起動せずにコードをダウンロードして実行する(サンドボックス内のコードを実行する)アプリケーションフレームワークがあります。



このソリューションは、大規模アプリケーションのチーム開発に最適です。 この記事では、Node.jsのクラスターとvmドメインを調べました。



参照:



  1. learn.javascript.ru/ajax-nodejs
  2. nodejs.org/api/cluster.html
  3. en.wikipedia.org/wiki/Model-View-Controller
  4. code-igniter.ru/user_guide/libraries/uri.html
  5. en.wikipedia.org/wiki/JSON
  6. nodejs.org/api/domain.html
  7. nodejs.org/api/vm.html
  8. https://github.com/pan-alexey/nodeigniter-github sources



All Articles