考虑以下简单的 Node.js 应用程序:
var http = require('http');
http.createServer(function() { }).listen(8124); // Prevent process shutting down
var requestNo = 1;
var maxRequests = 2000;
function requestTest() {
http.request({ host: 'www.google.com', method: 'GET' }, function(res) {
console.log('Completed ' + (requestNo++));
if (requestNo <= maxRequests) {
requestTest();
}
}).end();
}
requestTest();
它一个接一个地向 google.com 发出 2000 个 HTTP 请求。问题是它到达请求 5 并暂停大约 3 分钟,然后继续处理请求 6 - 10,然后再暂停 3 分钟,然后请求 11 - 15,暂停,依此类推。 编辑: 我尝试将 www.google.com 更改为 localhost,这是一个非常基本的 Node.js 应用程序,运行我的机器并返回“Hello world”,但我仍然会暂停 3 分钟。
现在我读到我可以增加连接池限制:
http.globalAgent.maxSockets = 20;
现在如果我运行它,它会处理请求 1 - 20,然后暂停 3 分钟,然后请求 21 - 40,然后暂停,依此类推。
最后,经过一番研究,我了解到我可以通过在请求选项中设置 agent: false 来完全禁用连接池:
http.request({ host: 'www.google.com', method: 'GET', agent: false }, function(res) {
...snip....
...它会很好地处理所有 2000 个请求。
我的问题,这样做是个好主意吗?是否存在可能导致 HTTP 连接过多的危险?为什么它会暂停 3 分钟,当然,如果我已经完成连接,它应该直接将其添加回池中,为下一个请求使用做好准备,那么为什么要等待 3 分钟呢?原谅我的无知。
如果做不到这一点,对于 Node.js 应用程序发出可能大量的 HTTP 请求而不会锁定或崩溃的最佳策略是什么?
我在 Mac OSX 10.8.2 上运行 Node.js 版本 0.10。
编辑:我发现如果我将上面的代码转换为一个 for 循环并尝试同时建立一堆连接,我在大约 242 个连接后开始出现错误。错误是:
Error was thrown: connect EMFILE
(libuv) Failed to create kqueue (24)
...还有代码...
for (var i = 1; i <= 2000; i++) {
(function(requestNo) {
var request = http.request({ host: 'www.google.com', method: 'GET', agent: false }, function(res) {
console.log('Completed ' + requestNo);
});
request.on('error', function(e) {
console.log(e.name + ' was thrown: ' + e.message);
});
request.end();
})(i);
}
我不知道一个负载很重的 Node.js 应用程序是否可以同时连接那么多。
最佳答案
您必须使用响应。
请记住,在 v0.10 中,我们登陆了streams2。这意味着 data 事件在您开始寻找它们之前不会发生。所以,你可以这样做:
http.createServer(function(req, res) {
// this does some I/O, async
// in 0.8, you'd lose data chunks, or even the 'end' event!
lookUpSessionInDb(req, function(er, session) {
if (er) {
res.statusCode = 500;
res.end("oopsie");
} else {
// no data lost
req.on('data', handleUpload);
// end event didn't fire while we were looking it up
req.on('end', function() {
res.end('ok, got your stuff');
});
}
});
});
但是,流在您不阅读时不会丢失数据的另一面是,它们实际上不会丢失数据如果您不阅读它!也就是说,它们开始时会暂停,您必须阅读它们才能得到任何东西。
所以,您的测试中发生的情况是,您正在发出一堆请求并且没有消耗响应,然后最终套接字被谷歌杀死,因为没有任何事情发生,它假设你已经死了。
在某些情况下,不可能使用传入的消息:也就是说,如果您没有在请求中添加 response 事件处理程序,或者您在在服务器上完全编写并完成 response 消息,而无需读取请求。在这种情况下,我们只会为您将数据转储到垃圾箱中。
但是,如果您正在监听 'response' 事件,则处理该对象是您的责任。在您的第一个示例中添加 response.resume(),您会看到它以合理的速度处理。
关于node.js - Node js - 连接池的 http.request() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15533448/
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。