Node.js
성능 문제
수색…
노드를 사용하여 장기 실행 쿼리 처리
Node는 단일 스레드이므로 장기 실행 계산의 경우 해결 방법이 필요합니다.
참고 : 이것은 "실행할 준비가되었습니다"예제입니다. jQuery를 가져와 필요한 모듈을 설치하는 것을 잊지 마십시오.
이 예제의 주요 논리는 다음과 같습니다.
- 클라이언트가 서버에 요청을 보냅니다.
- 서버는 별도의 노드 인스턴스에서 루틴을 시작하고 관련 태스크 ID와 함께 즉시 응답을 보냅니다.
- 클라이언트는 주어진 태스크 ID의 상태 업데이트를 위해 서버에 점검을 지속적으로 보냅니다.
프로젝트 구조 :
project
│ package.json
│ index.html
│
├───js
│ main.js
│ jquery-1.12.0.min.js
│
└───srv
│ app.js
├─── models
│ task.js
└─── tasks
data-processor.js
app.js :
var express = require('express');
var app = express();
var http = require('http').Server(app);
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var childProcess= require('child_process');
var Task = require('./models/task');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/../'));
app.get('/', function(request, response){
response.render('index.html');
});
//route for the request itself
app.post('/long-running-request', function(request, response){
//create new task item for status tracking
var t = new Task({ status: 'Starting ...' });
t.save(function(err, task){
//create new instance of node for running separate task in another thread
taskProcessor = childProcess.fork('./srv/tasks/data-processor.js');
//process the messages comming from the task processor
taskProcessor.on('message', function(msg){
task.status = msg.status;
task.save();
}.bind(this));
//remove previously openned node instance when we finished
taskProcessor.on('close', function(msg){
this.kill();
});
//send some params to our separate task
var params = {
message: 'Hello from main thread'
};
taskProcessor.send(params);
response.status(200).json(task);
});
});
//route to check is the request is finished the calculations
app.post('/is-ready', function(request, response){
Task
.findById(request.body.id)
.exec(function(err, task){
response.status(200).json(task);
});
});
mongoose.connect('mongodb://localhost/test');
http.listen('1234');
task.js :
var mongoose = require('mongoose');
var taskSchema = mongoose.Schema({
status: {
type: String
}
});
mongoose.model('Task', taskSchema);
module.exports = mongoose.model('Task');
data-processor.js :
process.on('message', function(msg){
init = function(){
processData(msg.message);
}.bind(this)();
function processData(message){
//send status update to the main app
process.send({ status: 'We have started processing your data.' });
//long calculations ..
setTimeout(function(){
process.send({ status: 'Done!' });
//notify node, that we are done with this task
process.disconnect();
}, 5000);
}
});
process.on('uncaughtException',function(err){
console.log("Error happened: " + err.message + "\n" + err.stack + ".\n");
console.log("Gracefully finish the routine.");
});
index.html :
<!DOCTYPE html>
<html>
<head>
<script src="./js/jquery-1.12.0.min.js"></script>
<script src="./js/main.js"></script>
</head>
<body>
<p>Example of processing long-running node requests.</p>
<button id="go" type="button">Run</button>
<br />
<p>Log:</p>
<textarea id="log" rows="20" cols="50"></textarea>
</body>
</html>
main.js :
$(document).on('ready', function(){
$('#go').on('click', function(e){
//clear log
$("#log").val('');
$.post("/long-running-request", {some_params: 'params' })
.done(function(task){
$("#log").val( $("#log").val() + '\n' + task.status);
//function for tracking the status of the task
function updateStatus(){
$.post("/is-ready", {id: task._id })
.done(function(response){
$("#log").val( $("#log").val() + '\n' + response.status);
if(response.status != 'Done!'){
checkTaskTimeout = setTimeout(updateStatus, 500);
}
});
}
//start checking the task
var checkTaskTimeout = setTimeout(updateStatus, 100);
});
});
});
package.json :
{
"name": "nodeProcessor",
"dependencies": {
"body-parser": "^1.15.2",
"express": "^4.14.0",
"html": "0.0.10",
"mongoose": "^4.5.5"
}
}
면책 조항 : 이 예제는 기본적인 아이디어를 제공하기위한 것입니다. 프로덕션 환경에서 사용하려면 개선이 필요합니다.
Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow