2014-10-24 2 views
0

은 (솔루션을 찾을 수)Node.js + Express 애플리케이션에서 동시성은 어떻게 작동합니까?

내가 코드 예제 내 질문을 시작하고 싶습니다 : 그들은이 완료되면 일부 작업을 수행하고 페이지 A 전화 doHeavyOperation()의 경우

var express = require('express'); 
var customModule = require('./custom-module'); 

var app = express(); 

// Page A 
app.get('/a', function(req, res) { 
    res.type('text/plain'); 
    customModule.doHeavyOperation(25, function(result) { 
     res.send('Page A, number = ' + result); 
    }); 
}); 

// Page B 
app.get('/b', function(req, res) { 
    res.type('text/plain'); 
    res.send('Page B'); 
}); 

app.listen(8082); 

, 그것은 내 실행 일부 정보를 사용자에게 보내는 콜백.

cutsom-module.js: 

exports.doHeavyOperation = function(number, callback) { 
    for (var i=0; i<2000000000; i++) { 
     number++; 
    } 
    callback(number); 
}; 

doHeavyOperation()의 경우 논리를 수행하고 콜백을 호출하는 데 약 5 초가 걸립니다. 내 브라우저에서 두 페이지 (localhost : 8082/a 및 localhost : 8082/b)를 열면 두 번째 페이지는 첫 번째 페이지가로드 될 때까지 기다려야합니다. 이는 요청이 동시에 처리되지 않음을 의미합니다.

대신 doHeavyOperation의 그들이 내 웹 응용 프로그램을 사용하려고하면서 내 고객을 동결 다른 기능이있을 수 있습니다. 예를 들어 사용자가 업로드 한 큰 이미지를 처리하고 일부 필터를 적용하는 등의 작업을 수행 할 수 있습니다. 1-3 초 정도 걸릴 수 있습니다. 그래서 내 웹 사이트를 동시에 사용하는 사람들이 100 명이된다면 커다란 문제가 발생할 것입니다. 예를 들어

는 아파치 + PHP는 꽤 좋은이 상황을 다루고있다. 스크립트 a.php가 일부 작업을 수행하는 동안 스크립트 b.php는 문제없이로드 될 수 있습니다.

어떻게 Node.js를 + Express에서이 동작을 달성하기 위해?

============================================== ==================================

kamituel의 의견에 Accodring, 내 decidion 새로운를 생성하는 것이 었습니다 "Heavy"계산을 수행하고 결과를 상위 프로세스로 리턴하는 프로세스. 이제 응용 프로그램이 원하는대로 작동합니다.

var express = require('express'); 

var app = express(); 

// Page A 
app.get('/a', function(req, res) { 
    // Creating child process 
    var child = require('child_process').fork('custom-module.js'); 
    // Sending value 
    child.send(25); 
    // Receiving result 
    child.on('message', function(result) { 
     res.type('text/plain'); 
     res.send('Page A, number = ' + result); 
    }); 
}); 

// Page B 
app.get('/b', function(req, res) { 
    res.type('text/plain'); 
    res.send('Page B'); 
}); 

app.listen(8082); 

맞춤 module.js : child_process here에 대한

function doHeavyOperation(number, callback) { 
    for (var i=0; i<2000000000; i++) { 
     number++; 
    } 
    callback(number); 
}; 

process.on('message', function(number) { 
    doHeavyOperation(number, function(result) { 
     process.send(result); 
    }); 
}); 

더 많은 정보

나는 내 코드를 수정했습니다.

답변

4

자바 스크립트 (Node.js도 마찬가지 임)는 (거의) 모든 JS 코드를 작성할 때 하나의 주 스레드를 사용합니다. 즉, 장기 실행 태스크 (예 : 큰 루프)가있는 경우이 태스크는 다른 코드 (콜백)의 실행을 차단합니다.

당신이 그것에 대해 무엇을 할 수 있습니까?

  • 루프를 더 작은 조각으로 나누고 때때로 컨트롤을 생성합니다 (예 : setTimeout/nextTick 등 사용). 나는. 0에서 1000까지 반복 할 수 있고, 다음 틱에서 루프 반복의 다음 1000을 수행 할 수 있습니다.
  • 새 프로세스를 생성하고 거기에서 무거운 작업을 처리합니다. 새로운 프로세스는 Node.js의 외부에 있기 때문에 차단하지 않습니다.