Node.js&Express.js HTTP应用超时设置
Node.js创建的HTTP服务器,其对于每个客户端请求的默认连接时长是2分钟(120秒)。如果在这个时间内,服务器没有发送响应信息(response),客户端的连接就会被重置。时间过长的请求响应会造成极差的用户体验,而且会造成IO的阻塞,对于单线程运行的Node.js应用来说,这种影响简直是灾难性的。合理的设置应用的超时时间非常重要。
1. Node.jshttp模块对超时的处理
在Node.js中,创建一个HTTP服务器使用http模块。
1.1 创建一个HTTP服务器
使用Node.js的http模块,可以很简单实现一个HTTP服务器:
const http = require('http');
const hostname = '127.0.0.1';
const port = 1337;
var server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
在上面的示例中,我们使用http.createServer创建了一个HTTP服务器server,它是一个http.Server实例。
在这个服务器中,我们添加了一个HTTP客户端请求监听函数,该函数包括两个参数:req和res。其中,req是一个客户端请求对象包含了客户端的请求信息,它是一个http.IncomingMessage实例。而res是服务器响应对象,它是一个http.ServerResponse实例,服务器处理完用户请求后通过访对象向客户端返回响应信息
1.2 http模块的超时设置
服务端的超时设置
对于一个HTTP服务器来说,我们可能会设置以下两种类型的超时:
用户请求的超时:即上例中http.IncomingMessage实例-req用户请求时间过长,会导致服务器停留在一个用户请求的接收状态,从而阻碍其它用户请求的进入。
服务器响应的超时:即上例中http.ServerResponse实例-res服务器响应时间过长,会导致用户长时间接收不到服务器响应信息,影响用户体验和其它用户请求的处理
Node.js HTTP服务器设置超时使用setTimeout()方法。http.Server、http.IncomingMessage和http.ServerResponse中都有一个setTimeout()方法。server.setTimeout()会设置所有用户请求和服务器响应的超时时间,而req.setTimeout()只能针对本次请求超时时间进行设置,res.setTimeout()只能针对本次请求的服务器响应超时时间进行设置。我们可以像下面这样在HTTP服务端设置超时:
将所有的用户请求和服务器响应超时时间设置为5秒:
server.setTimeout(5000);
对于某一个比较耗时的用户请求(如:图片上传),我们将用户请求超时时间设置为20秒:
req.setTimeout(20*1000);
对于一个需要在服务器进行较长时间处理用户请求,我们将服务器响应的超时时间设置为10秒:
res.setTimeout(10*1000);
客户端的超时设置
Node.js的http模块除了可以做为HTTP服务器使用,来处理和响应用户请求外。还可以做为HTTP客户端来使用,来发送客户端请求。
http模块中的ClientRequest对象实现了HTTP客户端功能,该对象同样提供了一个setTimeout()方法,用于设置请求的超时时间,当服务器超时未响应时,客户端对象会重置到服务器的链接。
如,我们可以像下面这样创建一个HTTP客户端,并设置请求的超时时间:
const http = require('http');
const options = {
host: 'itbilu.com',
method: 'GET',
port: 80,
path: '/'
}
var req = http.request(options);
req.setTimeout(2000);
req.on('response', (res) => {
res.setEncoding('utf8');
res.on('data', function(chunk){
console.log('收到数据:%s', chunk);
});
res.on('end', function(){
console.log(res.trailers);
});
});
req.end();
注意:所有的超时设置都是以毫秒为单位,当设置为0时表示永不超时。
2. Express.js的超时设置
Express.js框架是在http模块的基础上构建的一个HTTP服务器模块,因此我们也可以像http模块那样设置所有HTTP请求的用户请求和服务器响应超时时间,也可以针对某一个HTTP请求设置用户请求和服务器响应超时时间。
2.1 Express.js所有的请求超时时间
类似Node.js原生的HTTP服务器设置,我们对Express.js应用所有请求的用户请求和服务器响应超时时间进行设置:
var app = require('../app'); app.set('port', process.env.PORT || 3000); var server = app.listen(app.get('port'), function() { debug('Express服务器运行于:' + server.address().port); }); server.setTimeout(1000); server.on('timeout', function(){ console.log('超时了'); })
2.2 使用Express.js中间件设置超时
Express.js提供了强大的中间件机制,利用这一机制我们可以更为灵活的设置HTTP服务器超时时间。
如,我们可以在app.js文件中添加如下处理程序,分别设置请求和服务器响应的超时时间,当然也可以只设置请求超时或服务器响应超时时间:
app.use(function(req, res, next) { // 设置所有HTTP请求的超时时间 req.setTimeout(5000); // 设置所有HTTP请求的服务器响应超时时间 res.setTimeout(5000); next(); });
对比较某一个比较耗时的用户请求,或需要较多响应时间才能完成处理的请求,我们可以其路由处理方法或路由中间件中单独设置超时时间:
router.post('/file', function(req, res) {
req.setTimeout(20*1000)
// 一些处理……
});
转自:https://itbilu.com/nodejs/core/4yHX3Aiie.html
参考:https://juejin.cn/post/6871176409278332935

浙公网安备 33010602011771号