在高负载下连接 nodejs 中的 EADDRNOTAVAIL - 如何更快地释放或重用 TCP 端口?

pet*_*ter 5 port limit node.js coffeescript express

我有一个基于 express-framework 的类似 wiki 的小型 Web 应用程序,它使用弹性搜索作为后端。对于每个请求,它基本上只转到弹性搜索数据库,检索对象并返回由把手模板引擎呈现的对象。与弹性搜索的通信通过 HTTP

只要我只有一个 node-js 实例在运行,这个方法就很好用。在我更新我的代码以使用集群后(如nodejs-documentation 中所述,我开始遇到以下错误:connect EADDRNOTAVAIL

当我运行 3 个或更多 python 脚本时,会出现此错误,这些脚本不断从我的服务器检索一些 URL。使用 3 个脚本,我可以检索约 45,000 个页面,其中运行 4 个或更多脚本,在 30,000 到 37,000 个页面之间仅运行 2 或 1 个脚本,半小时后我停止了它们,分别检索了 310,000 页和 160,000 页。

我发现了这个类似的问题并尝试更改,http.globalAgent.maxSockets但没有任何效果。

这是代码的一部分,用于侦听 URL 并从弹性搜索中检索数据。

app.get('/wiki/:contentId', (req, res) ->
    http.get(elasticSearchUrl(req.params.contentId), (innerRes) ->
        if (innerRes.statusCode != 200)
            res.send(innerRes.statusCode)
            innerRes.resume()
        else
            body = ''
            innerRes.on('data', (bodyChunk) ->
                body += bodyChunk
            )
            innerRes.on('end', () ->
                res.render('page', {'title': req.params.contentId, 'content': JSON.parse(body)._source.html})
            )
    ).on('error', (e) ->
        console.log('Got error: ' + e.message)  # the error is reported here
    )
)
Run Code Online (Sandbox Code Playgroud)

更新:

在深入研究之后,我现在明白了问题的根源。我netstat -an | grep -e tcp -e udp | wc -l在测试运行期间多次运行该命令,以查看使用了多少端口,如Linux: EADDRNOTAVAIL (Address not available) error 中所述。我可以观察到,在我收到 EADDRNOTAVAIL 错误时,使用了 56677 个端口(而不是正常情况下的 ~180 个)

此外,当仅使用 2 个同步脚本时,所用端口的数量在 40,000 (+/- 2,000) 左右饱和,这意味着每个脚本使用约 20,000 个端口(这是 node-js 在新端口之前清理旧端口的时间)创建)并且运行它的 3 个脚本会破坏 56677 个端口(~60,000)。这解释了为什么它在 3 个请求数据的脚本时失败,但在 2 个时没有。

所以现在我的问题变成了 - 我怎样才能强制 node-js 更快地释放端口或一直重用同一个端口(这将是更好的解决方案)

谢谢

pet*_*ter 4

目前,我的解决方案是将agent我的请求选项设置为此false应该,根据文档

选择退出与代理的连接池,默认请求连接:关闭。

因此,我使用的端口数量不超过 26,000 - 这仍然不是一个很好的解决方案,甚至更多,因为我不明白为什么重用端口不起作用,但它暂时解决了问题。