Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Node.js中处理多个并行HTTP请求_Node.js - Fatal编程技术网

在Node.js中处理多个并行HTTP请求

在Node.js中处理多个并行HTTP请求,node.js,Node.js,我知道节点是非阻塞的,但我刚刚意识到http.listen(8000)的默认行为意味着所有http请求一次只能处理一次。我知道我不应该对此感到惊讶(这是端口的工作原理),但这确实让我想知道如何编写代码,以便处理多个并行HTTP请求 那么,编写服务器的最佳方法是什么,这样它就不会占用端口80,并且长时间运行的响应不会导致长时间的请求队列 为了说明这个问题,请尝试运行下面的代码,并将其同时加载到两个浏览器选项卡中 var http = require('http'); http.createServ

我知道节点是非阻塞的,但我刚刚意识到
http.listen(8000)
的默认行为意味着所有http请求一次只能处理一次。我知道我不应该对此感到惊讶(这是端口的工作原理),但这确实让我想知道如何编写代码,以便处理多个并行HTTP请求

那么,编写服务器的最佳方法是什么,这样它就不会占用端口80,并且长时间运行的响应不会导致长时间的请求队列

为了说明这个问题,请尝试运行下面的代码,并将其同时加载到两个浏览器选项卡中

var http = require('http');
http.createServer(function (req, res) {
    res.setHeader('Content-Type', 'text/html; charset=utf-8');
    res.write("<p>" + new Date().toString() + ": starting response");
    setTimeout(function () {
        res.write("<p>" + new Date().toString() + ": completing response and closing connection</p>");
        res.end();
    }, 4000);
}).listen(8080);
var http=require('http');
http.createServer(函数(req,res){
res.setHeader('Content-Type','text/html;charset=utf-8');
res.write(“”+新日期().toString()+”:开始响应”);
setTimeout(函数(){
res.write(“”+新日期().toString()+”:完成响应并关闭连接“

”; res.end(); }, 4000); }).听(8080);
您误解了节点的工作原理。上面的代码可以接受来自数百或数千个客户端的TCP连接,读取HTTP请求,然后等待在其中烘焙的4000毫秒超时,然后发送响应。每个客户端将在大约4000+少量毫秒内得到响应。在设置超时期间(以及任何I/O操作期间),节点可以继续处理。这包括接受额外的TCP连接。我测试了你的代码,每个浏览器都在4s内得到响应。第二个不需要8秒,如果你认为它是这样工作的话

我通过键盘在4个选项卡中以最快的速度运行了
curl-s localhost:8080
,时间戳中的秒数为:

  • 54至58
  • 54至58
  • 55至59
  • 56至00
  • 这里没有问题,尽管我能理解你怎么会认为有问题。如果节点按照您的帖子所建议的那样工作,它将完全崩溃

    下面是另一种验证方法:

    for i in 1 2 3 4 5 6 7 8 9 10; do curl -s localhost:8080 &;done                                                                                                                                                                       
    

    您的代码可以接受多个连接,因为作业是在setTimeout调用的回调函数中完成的

    但是如果你不去做一件繁重的工作。。。那么node.js确实不会接受其他多个连接!SetTimeout意外地释放了进程,因此node.js可以接受其他作业,并且您的代码在其他“线程”中执行


    我不知道哪种方法是正确的。但它似乎就是这样工作的。

    我使用以下代码来测试请求处理

    app.get('/', function(req, res) {
      console.log('time', MOMENT());  
      setTimeout( function() {
        console.log(data, '          ', MOMENT());
        res.send(data);
        data = 'changing';
      }, 50000);
      var data = 'change first';
      console.log(data);
    });
    
    因为这个请求不需要太多的处理时间,除了50秒的setTimeout和所有超时都像通常一样一起处理

    响应3一起请求-

    time moment("2017-05-22T16:47:28.893")
    change first
    time moment("2017-05-22T16:47:30.981")
    change first
    time moment("2017-05-22T16:47:33.463")
    change first
    change first            moment("2017-05-22T16:48:18.923")
    change first            moment("2017-05-22T16:48:20.988")
    change first            moment("2017-05-22T16:48:23.466")
    
    在这之后我进入了第二阶段。。。i、 例如,如果我的请求需要花这么多时间来处理同步文件或其他需要时间的事情,该怎么办

    app.get('/second', function(req, res) {
        console.log(data);
        if(req.headers.data === '9') {
            res.status(200);
            res.send('response from api');
        } else {
            console.log(MOMENT());
            for(i = 0; i<9999999999; i++){}
            console.log('Second MOMENT', MOMENT());
            res.status(400);
            res.send('wrong data');
        }
    
        var data = 'second test';
    });
    

    因此,对于所有异步函数,节点中都有一个虚拟线程,节点在完成以前的请求(如fs、mysql或调用API)之前会接受其他请求,但它会将自身保持为单个线程,并且在以前的所有请求完成之前不会处理其他请求。

    浏览器会阻止其他相同的请求。如果您从不同的浏览器调用它,那么它将并行工作。

    您是正确的。是Chrome做的。至少对我来说,第二个请求在第一个请求返回之前是不会发出的。即使chrome通常也应该允许每个源最多6个并发连接。我知道。这就是为什么我感到惊讶,并假设它是节点。你知道为什么Chrome不能同时发送这两个请求吗?坦率地说,我不相信OP声称Chrome正在按照我的上述评论序列化请求。浏览器和服务器之间的完整交互非常复杂。但是如果没有代码来重复这个问题,我就无法进一步评论。
    undefined
    moment("2017-05-22T17:43:59.159")
    Second MOMENT moment("2017-05-22T17:44:40.609")
    undefined
    moment("2017-05-22T17:44:40.614")
    Second MOMENT moment("2017-05-22T17:45:24.643")