如何使Node.js有效地处理多个请求? [英] How to make Node.js handle multiple requests efficiently?

查看:163
本文介绍了如何使Node.js有效地处理多个请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个Node.js应用程序,该应用程序接受来自客户端的传入请求,然后调用远程服务器上的某些Web服务以检索数据.

I am trying to write a Node.js application which accepts incoming requests from client and then make a call to some web service on the remote server to retrieve data.

const express = require('express')
const request = require('request')
const moment = require('moment')

const app = express()

app.get('/', (req, res) => {

    request('http://localhost/sleep.php', (error, response, body) => {
        res.send('get data at ' + moment().format())
    })

})

app.listen(3000)

远程服务是用PHP编写的:

The remote service is written in PHP:

<?php

    sleep(10);
    echo 'Return something!';

问题在于,如果新请求进入,则Node.js将被阻止,直到完成最后一个回调为止.如何解决这个问题?有什么想法吗?

The problem is that if the new request comes in then Node.js is blocked until it has finished the last callback. How to fix this? Any ideas?

更新:

实际上,我同时通过Firefox发出了两个请求,第二个请求花费了将近20秒.

I actually make two requests at the same time via Firefox and the second request spent almost 20 seconds.

请在此处查看图片

推荐答案

下面是快速演示:浏览器不会通过管道传递对同一URL的并发请求,但通常会提供不同的URL.为查询字符串添加一个不同的值是解决此问题的一种技术:例如,localhost:3000/?1517849200341使用Date.now().

Here's a quick demonstration that concurrent requests for the same URL will not be pipelined by the browser, but different URLs generally will. Adding a distinct value to the query string is a technique to work around this: localhost:3000/?1517849200341 using Date.now() for instance.

(广义上讲,流水线在HTTP/1.1中被禁用,但是浏览器将在同一端使用多个TCP连接.通过设置最大流数,流水线是HTTP/2的一部分.我真的不知道这是什么表示或如何解释以下结果.)

(Broadly speaking, pipelining is disabled in HTTP/1.1, but browsers will use multiple TCP connections to the same end. Pipelining is part of HTTP/2 by setting the maximum number of streams. I don't really know what this means or how to interpret the result below.)

async function log(fn) {
  console.log(Date());
  await Promise.all(fn());
  console.log(Date());
}

const req1 = 'https://httpbin.org/delay/1';
const req2 = 'https://nghttp2.org/httpbin/delay/1';

const req3 = 'https://httpbin.org/delay/1?a';
const req4 = 'https://httpbin.org/delay/1?b';
const req5 = 'https://httpbin.org/delay/1?c';
const req6 = 'https://httpbin.org/delay/1?d';

const req7 = 'https://nghttp2.org/httpbin/delay/1?a';
const req8 = 'https://nghttp2.org/httpbin/delay/1?b';
const req9 = 'https://nghttp2.org/httpbin/delay/1?c';
const req10 = 'https://nghttp2.org/httpbin/delay/1?d';

btn1.addEventListener('click', () => log(() => [
  fetch(req1),
  fetch(req1),
  fetch(req1),
  fetch(req1),
  fetch(req1),
]));

btn2.addEventListener('click', () => log(() => [
  fetch(req2),
  fetch(req2),
  fetch(req2),
  fetch(req2),
  fetch(req2),
]));

btn3.addEventListener('click', () => log(() => [
  fetch(req1),
  fetch(req3),
  fetch(req4),
  fetch(req5),
  fetch(req6),
]));

btn4.addEventListener('click', () => log(() => [
  fetch(req2),
  fetch(req7),
  fetch(req8),
  fetch(req9),
  fetch(req10),
]));

<button id=btn1>HTTP/1.1, same URLs</button>
<button id=btn2>HTTP/2, same URLs</button>
<button id=btn3>HTTP/1.1, different URLs</button>
<button id=btn4>HTTP/2, different URLs</button>

这篇关于如何使Node.js有效地处理多个请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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