在节点应用程序中触发许多请求,导致套接字挂起/ ECONNRESET错误

我试图为我的应用程序写一个testing,在那里我使用了express-brute来防止暴力攻击。

我有以下testing:

it('should return 429 status after 1000 attempts', function (done) { this.timeout(5000); var counter = 0; var makeRequest = function (count, done) { counter++; request(app) .post('/login') .send({ username: 'a+' + count + '@b.com', password: 'wrong' + count }) .end(function (err, res) { if (err) { console.log('failed request #', counter); return done(err); } if (counter < 1001) { makeRequest(counter, done); } else { res.header.location.should.equal('/account/login'); res.statusCode.should.equal(429); done(); } }); } makeRequest(counter, done); }); 

哪个抛出错误:

错误:套接字挂断有时它是错误:读ECONNRESET

它总是在#225的连接

同样的testing(只有20个左右的请求)工作正常(如果我改变我的快速configuration)

什么原因导致错误?

我没有正确closures/处理连接吗?

你使用什么操作系统?

可能需要增加允许的开放套接字的数量。

例如在这里看到: 如何增加在osx套接字负载testing的限制?

我能够通过使用这个代码来复制资源耗尽问题,我相信这些代码复制了您的问题的要点:

 var request = require("supertest"); var express = require("express"); var app = express(); app.post('/login', function (req, res, next) { res.send('Success!'); } ); var server = app.listen(); var counter = 0; function makeRequest(count, done) { counter++; request(app) .post('/login') .send({ username: 'a+' + count + '@b.com', password: 'wrong' + count }) .end(function (err, res) { if (err) { console.log('failed request #', counter); done(err); } if (counter < 1001) { console.log(counter); makeRequest(counter, done); } else { console.log(res); done(); } }); } function done(err) { process.exit(1); } makeRequest(counter, done); 

像这样运行它:

 $ (ulimit -n 100; node test.js ) 

我必须使用ulimit因为无论是什么原因导致您的问题不会发生在我的操作系统上。 ulimit命令将打开文件的数量限制为100.当我像上面那样运行它时,请求编号89失败。 (有一些其他文件打开运行该脚本,这解释了为什么它失败的请求89而不是100.)

我可以让代码运行到完成,如果我更改代码,以便我从我的应用程序创build一个服务器:

 var app = express(); // ... var server = app.listen(); 

我使用request server而不是app

 request(server) .post('/login') // ... 

所以使用app.listen()返回的值应该解决这个问题。