网络请求后,节点应用程序不会终止?

时间:2014-05-16 17:24:09

标签: node.js

我正在从文本文件中读取ID并发出一些RESTful请求。它可以工作,但是当所有ID都已运行时,节点应用程序仍然在运行。

main.js:

var fs = require('fs');
var http = require('http');

var ids = fs.readFileSync('test.txt', { encoding: 'utf8' });
ids = ids.split('\n');
var options = {
    hostname: 'internalhost',
    port: 80,
    path: '',
    method: 'DELETE'
};
for (var i = 0; i < ids.length; i++) {
    options.path = '/thing/' + ids[i];
    console.log('Deleting thing ' + ids[i]);

    var req = http.request(options, function(res) {
        console.log('Status: ' + res.statusCode);
    });

    req.on('error', function(e) {
        console.log('Problem with request: ' + e.message);
    });

    req.end();
}

请求成功完成但在最后一个请求后,应用程序继续运行。我在打印响应的状态代码后立即尝试添加res.end(),但后来发现res没有方法end的错误。

这里发生了什么?

2 个答案:

答案 0 :(得分:3)

看来你是suffering from a side-effect of HTTP keep-alives。当TCP连接打开时,节点不会退出,HTTP Agent会使TCP连接无限期地打开。

您已经提到保持活动对您有益,因此您的选择有限。

  • 只需禁用Agent即可停用保持活动,因此这不是一个选项。

  • 您可以手动管理和跟踪您的请求,完成所有请求后,请致电process.exit。然而,我不喜欢这样,因为它是一种相当钝的乐器。如果您正在运行其他异步操作(例如数据库调用),则可能会在这些操作完成之前意外终止您的应用程序。

  • 您可以手动管理和跟踪您的请求。完成所有操作后,您可以遍历Agent实例的sockets属性并关闭所有延迟套接字。 (警告calling close on an already closed socket throws。)

    这是一种更安全的方法,因为在应用程序退出之前,其他未完成的操作将被允许完成。

  • 您可以升级到节点≥0.11.4。 (实际上,您可能希望等到释放0.12稳定版。)下一个节点版本有一个greatly improved Agent implementation unref个空闲套接字保留在Agent的连接池中。换句话说,如果唯一的开放TCP连接是被保留以作为保持连接的重用连接,则节点可以退出。

  • 您还可以从不稳定分支中删除new Agent implemention并将其用于应用的请求,而不是您的节点版本提供的默认Agent(这可能就是我要做的。)

答案 1 :(得分:2)

只有在没有待处理的待处理事件时,

节点才会终止。在这种情况下,我认为连接仍处于打开状态,因此您可以通过调用res.socket.end()res.destroy()或@ExplosionPills建议手动销毁它,只需在所有请求完成后调用process.exit即可。您可以使用async模块来帮助您实现此目标。