阅读数:

nodejs timeout

0

说明

正常的网络请求无非都是
client —req—>
<—res–server
,由于业务需要或者xx要求,需要对请求做超时限制。一个请求的timeout可分为三种:
1、client requset timeout
指的的是客户端请求超时设置,比如5s,意思是client从发起请求开始计时,如果超过5s,server还没有响应header
返回,即视为请求超时;
2、server response timeout
指的是服务器端响应超时设置,比如5s,意思是server从发送数据开始计时,如果超过5s,client还没有全部接收数据,即视为响应超时;
3、server timeout
指的是server要维持和client的连接处于空闲的时间,比如5s,指的是client和server建立连接5s后,还没响应,连接就会失效。
现在要实践的是2和3,client timeout不做扩展了

实验

  • server response timeout
    nodejs express框架,router可以灵活的设置一个或者多个中间价,比如常见的auth,passport,ratelimit以及现在要说的timeout等等。比如路由
1
2
3
router.post('/hello', function (req, res, next) {
res.send('world');
})

一个的post请求,我们想要的效果是5s内server res timetou,那么自然想到的是express中间价,这里我用的是
connect-timeout 就可以轻松的实现。

1
2
3
4
5
6
import timeout from 'connect-timeout';
router.post('/hello', timeout(5s), function (req, res, next) {
setTimeout(() =>{
res.send('world');
},6*1000); //模拟业务处理需要6s
})

然后我们可以用postman或者restclient工具进行模拟请求,发现5s的时候客户端会返回timeout

  • server timeout
    上面的业务需要6s,比如是非常耗时的处理需要3min(当然如果是这样就不建议http同步处理了,最好采用异步处理的方式),但为了测试timeout,我们还是鲁莽一次。这次不设置server res timeout
    1
    2
    3
    4
    5
    router.post('/hello', function (req, res, next) {
    setTimeout(() =>{
    res.send('world');
    },3*60*1000); //模拟业务处理需要3min
    })

然后我们可以用postman或者restclient工具进行模拟请求,发现2min的时候客户端自动取消请求了。这不是我们想要的,这是为什么呢,查阅nodejs官方文档发现,server client会有连接超时设置 默认2min
timeout1
但是我们的业务需要3min怎么办,继续看文档发现 servertimeout 可以设置
timeout2
试试0 表示无限制

1
2
server.timeout = 0;
server.listen(port);

再请求,发现在3min的时候数据返回了world,符合业务要求。

但是这样会有问题,无限等待会对服务器造成压力,尤其是请求量大的时候。或者其他路有响应很快,这时候可以结合中间件进行双重控制。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
app.js
server.timeout = 0;
server.listen(port);
router.js
router.post('/hello',timeout(4*60s), function (req, res, next) {
setTimeout(() =>{
res.send('world');
},3*60*1000); //模拟业务处理需要3min
})
router.post('/world',timeout(4s), function (req, res, next) {
res.send('hello');
})

最后

如有疑问或者更好的方案留言下方……^_^


^-^欢迎回复交流^-^


0
赏点咖啡钱^.^