node.js - Node.js http 请求导致 CLOSE_WAIT
问题描述
我创建了一个 JavaScript 程序,它检查网络上各种设备的状态,并将它们的状态报告给 MQTT 服务器,以便与我的家庭自动化仪表板集成。为了检查设备状态,我打开了一个连接(HTTP、HTTPS 或通用 TCP)。如果连接成功,设备会报告为 up。如果失败或超时,则报告为停机。然后我结束连接。
这运行良好,除了当我连接到我的互联网路由器的 HTTP 管理界面时。使用路由器,连接卡在 CLOSE_WAIT 中。
netstat -t
tcp 24160 0 uno.home:52544 router.0.168.192.i:http CLOSE_WAIT
tcp 24160 0 uno.home:49742 router.0.168.192.i:http CLOSE_WAIT
tcp 24160 0 uno.home:50820 router.0.168.192.i:http CLOSE_WAIT
tcp 24160 0 uno.home:48084 router.0.168.192.i:http CLOSE_WAIT
...
这将一直持续到我关闭程序或内核不再能够分配 TCP 内存。
我正在对 Nginx Web 服务器和 Portainer(基于 Web 的容器管理器)运行相同的检查。这些都不会导致相同的 CLOSE_WAIT 问题。我怀疑是路由器出了问题,但我想知道我的代码中是否有任何可以帮助缓解问题的地方。
这是执行 HTTP 检查的函数:
/**
* Connect to an HTTP server and report the result.
* @param {string} name A friendly name given to the service check.
* @param {string} host The server's hostname or IP address.
* @param {number} port The TCP port number the server listens on.
* @param {string} path The directory and file name portion of the URL (e.g. /index.html)
*/
function httpCheck(name, host, port, path) {
const httpRequest = http.get(`http://${host}:${port}${path}`, (response) => {
if (debug)
console.log(`HTTP check for http://${host}:${port}${path} returned: ${response.statusCode}`);
if (response.statusCode < 400)
publishStatus(name, config.statusMsg.success);
else
publishStatus(name, config.statusMsg.failure);
});
httpRequest.on('data', (chunk) => {
let data = chunk; // Read and throw away.
});
httpRequest.on('close', () => {
httpRequest.end();
});
httpRequest.on('error', (err) => {
publishStatus(name, config.statusMsg.failure);
httpRequest.end();
});
}
httpRequest.end()
可能是多余的。我添加了这些以尝试解决此问题。我还添加了这样的.on('data')
想法,路由器的 Web 服务器可能会等待我在它认为完整之前阅读整个页面。
我还简要地考虑过只做一个 HEAD 请求,但路由器给出了一个“501:方法未实现”错误。
同样,我觉得奇怪的是,我对 Nginx 和 Portainer 的检查在这段代码中运行良好。但是,也许我缺少一些东西。是否有可能改进代码以避免TIME_WAIT?
解决方案
推荐阅读
- php - 如何多次回显一个字母,为每个新打印更改一个以上的变量?
- c# - 如何从 Material Design for XAML 覆盖 ComboBox ToggleButton?
- java - selenium chromeDriver 的端口是什么意思?
- python - 如何仅获取列表中不带括号的第一个数字?
- javascript - 如何一起删除表行和数组索引
- rust - 如何使用另一个结构覆盖可变引用中的所有字段?
- r - 检查几个句子是否相同
- python - 在 arctan 中找到 0-360 的角度
- java - 如何在 Swagger 中将 OptionalInt 参数作为整数处理?
- discord - 请帮我提供向频道发送消息的代码