Node.js是否可以一一处理客户端请求? [英] Does Node.js handle client requests one by one?

查看:77
本文介绍了Node.js是否可以一一处理客户端请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Node.js是否可以一一处理客户端请求?我有一个项目,正在使用Node.js作为服务器端代理.根据我的理解,如果您使用回调进行响应,则Node.js应该立即响应新请求,但实际上Node.js直到完成上一个回调后才会响应新请求.这是正确的操作还是代码使用有误?请帮我.非常感谢你.下面是将请求重新发送到后端服务的代码.

Does Node.js handle the client requests one by one? I have a project, which is using Node.js as a server-side proxy. According to my understanding, if you use a callback for a response, Node.js should respond to the new request without any delay, but actually the Node.js won't respond to the new request until it has finished the last callback. Is this the correct action or is there some incorrect code usage? Please help me on this. Thank you very much. Below is the code for re-sending requests to the back-end service.

var request = require('request');
var http = require('http');

function apiService(){}

apiService.prototype.get = function (context, payload, callback, url){
    return this.requestAPI(context, payload, callback, url, "GET");
}
apiService.prototype.post = function(context, payload, callback, url){
    return this.requestAPI(context, payload, callback, url, "POST");
}
apiService.prototype.del = function(context, payload, callback, url){
    return this.requestAPI(context, payload, callback, url, "DELETE");
}
apiService.prototype.requestAPI = function(context, payload, callback, url, method){

    var config = context.config;
    var targetUrl = config.APIHost
                    + (config.port == null ? "": (":" + config.port)) 
                    + "/" 
                    + config.baseDir
                    + "/"
                    + url;

    var requestObj = {
            url : targetUrl,
            json : true,
            pool: new http.Agent()
        }

    if (config.proxy != null){
        requestObj.proxy = config.proxy;
    }

    switch (method){
        case "POST":
            requestObj.body = payload;
            request.post(requestObj, function (err, resp, body){
                if (err){
                    callback(err);
                    return;
                }
                callback(null, body);
            });
            break;
        case "GET":
            var queryString = "";
            for (att in payload){
                if (queryString != "")
                    queryString += "&";
                queryString += att.toString() + "=" + payload[att];
            }
            if (queryString!="")
                requestObj.url += "?" + queryString;

            request.get(requestObj, function (err, resp, body){
                if (err){
                    callback(err);
                    return;
                }
                callback(null, body);
            });
            break;
        case "DELETE":
            requestObj.body = payload;
            request.del(requestObj, function (err, resp, body){
                if (err){
                    callback(err);
                    return;
                }
                callback(null, body);
            });
            break;
    }
}

Current process

client       request1  ->       Node
client       request2  ->       Node
                                Node    server request1    ->backend
                                Node (waiting for event loop)
                                Node     <- server response1 backend
client       <- response1       Node
                                Node    server request2    ->backend
                                Node     <-  server response2 backend
client       <- response2       Node 
What I think it should be

  client       request1  ->       Node
client       request2  ->       Node
                                Node    server request1 ->     backend
                                Node (won't waiting for event loop)
                                Node    server request2 ->     backend
                                Node    <- server response2    backend
client       <-response2        Node
                                Node    <- server response1    backend 
client       <-response1        Node

已更新:

               var params = {
						action : 'list'
				};
				$http.post('../../service/buildingBlockService', params)
				.success(function(buildingBlocks){
						callback(null, buildingBlocks);
					}).error(function(error){
						callback(error);
					})

客户端请求来自Angular $http.在一页上,同时有多个请求.根据我的Fiddler监视器,来自浏览器的请求无需等待就可以发送,但是服务器重新发送的请求是一对一的.

The client requests are from Angular $http. On one page, there are several requests at the same time. According to my Fiddler monitor, the requests from the browser are sent without waiting, but the server re-send is one by one.

app.post('/service/buildingBlockService', function (ctx, payload, req, res) {  
		var service1 = require('./service/buildingBlockService');
		var service = new service1();
		service.service(ctx, payload, function(error, result){
			res.send(200, result);
		});
	});
	

已更新:服务器请求的中间层.

Updated: The middle layer of server request.

var service = require('./apiService');

function BuildingBlockService(){
}

BuildingBlockService.prototype.init = function(){}

BuildingBlockService.prototype.service = function(context, payload, callback) { 
	var apiService = new service() 
	var params = payload;
	switch (params.action){
		case "list":
		default:
			apiService.get(context, null, callback, "BuildingBlocks");
			break;
	}
	 
};  
  
module.exports = BuildingBlockService;  

推荐答案

Node.js是否可以一一处理客户端请求?

Does Node.js handle client requests one by one?

是的,node.js运行您的JS单线程.这意味着在任何给定时间,只有一个JS执行线程正在运行.因此,如果您有两个这样的请求:

Yes and No. node.js runs your JS single threaded. That means that only one JS thread of execution is running at any given time. So, if you had two requests like this:

// don't use this in real code, it's to simulate a point
function spin(t) {
    var start = Date.now();
    while (Date.now() < start + t) {}
}

app.post("/route1", req, res) {
    console.log("starting processing of /route1 request");
    // simulate taking several seconds of pure CPU to make a response
    spin(2000);
    res.send("done 1");
    console.log("finished processing of /route1 request");
}

app.post("/route2", req, res) {
    console.log("starting processing of /route2 request");
    // simulate taking several seconds of pure CPU to make a response
    spin(2000);
    res.send("done 2");
    console.log("finished processing of /route2 request");
}

然后/route1请求紧随其后的是/route2请求,然后node.js服务器将处理/route1请求,并且直到该请求完成后才能执行其他任何操作,因为CPU一直处于忙碌状态整个时间.

And a /route1 request was immediately followed by a /route2 request, then the node.js server would process the /route1 request and not be able to do anything else until it was done with that request because the CPU was kept busy the entire time.

因此,这将产生如下日志:

So, this would produce a log like this:

starting processing of /route1 request
finished processing of /route1 request
starting processing of /route2 request
finished processing of /route2 request


但是,纯粹出于CPU原因,请求花费很长时间是相对罕见的.通常,请求涉及某种I/O(要读取的文件,数据库查询,要联系的其他服务器等).如果该I/O是使用异步IO而不是同步IO以异步方式完成的,则多个请求可以轻松地同时在发送中,并且可以同时在发送中,因为node.js服务器正在等待对于完成的I/O请求,可以免费服务其他请求,也可以满足其他请求.


But, it is relatively rare that requests take a long time purely for CPU reasons. Often requests involve some sort of I/O (files to read, database queries, other servers to contact, etc...). If that I/O is done in an async fashion using async IO and not using synchronous IO, then multiple requests can easily be in flight at the same time and will be in flight at the same time because while the node.js server is waiting for I/O requests to complete, it is free to serve other requests and will serve other requests.

因此,如果您有以下服务器代码:

So, if you had this server code:

app.post("/route1", req, res) {
    console.log("starting processing of /route1 request");
    // simulate taking several seconds of pure CPU to make a response
    request('http://www.google.com', function (error, response, body) {
        if (!error && response.statusCode == 200) {
            res.send("done 1");
            console.log("finished processing of /route1 request");
        }
    });
}

app.post("/route2", req, res) {
    console.log("starting processing of /route2 request");
    // simulate taking several seconds of pure CPU to make a response
    request('http://www.google.com', function (error, response, body) {
        if (!error && response.statusCode == 200) {
            res.send("done 2");
            console.log("finished processing of /route2 request");
        }
    });
}

在/route1请求之后紧接着是/route2请求,那么您可能会看到此日志(无法保证/route1和/route2响应完成的顺序-它们可以按任何顺序排列),但是两者响应将被并行处理:

And a /route1 request was immediately followed by a /route2 request, then you would likely see this log (the order that the /route1 and /route2 responses finishes is not guaranteed - they could be in any order), but both responses will be processed in parallel:

starting processing of /route1 request
starting processing of /route2 request
finished processing of /route1 request
finished processing of /route2 request


如果您的node.js代理服务器似乎表现出串行处理行为而不是并行处理行为,则可能是由于您确实具有以下能力而在实现代理方面存在某种实现问题:同时有多个请求在飞行中.


If your node.js proxy server appears to be exhibiting serial processing behavior rather than parallel processing behavior, then that it could be that there is some sort of implementation issue in how you are implementing the proxy as it is certainly capable of having multiple requests in flight at the same time.

这篇关于Node.js是否可以一一处理客户端请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆