NodeJS因多个请求而崩溃

时间:2015-03-04 11:54:21

标签: node.js sockets express crash

我的nodejs服务器实时随机崩溃(并且总是在具有10+线程请求的Web压力工具上)。以下是我认为是根本原因的代码。

main.js

--------
app = express():
---------
app.get('/image/*', actions.download);

actions.js

var request = require('request');
exports.download = function(req, res){
var url = <Amazon s3 URL>;
req.pipe(request(url)).pipe(res);
};

当服务器崩溃时,我在nohup中遇到错误

stream.js:94
throw er; // Unhandled stream error in pipe.
^
Error: socket hang up
at createHangUpError (http.js:1476:15)
at Socket.socketOnEnd [as onend] (http.js:1572:23)
at Socket.g (events.js:180:16)
at Socket.emit (events.js:117:20)
at _stream_readable.js:943:16
at process._tickCallback (node.js:419:13)

我尝试使用sudo NODE_DEBUG=net node main.js并使用10个线程进行压力测试时的详细日志

NET: 3017 Socket._read readStart 
NET: 3017 afterWrite 0 { domain: null, bytes: 335, oncomplete: [Function: afterWrite] } 
NET: 3017 afterWrite call cb 
NET: 3017 onread ECANCELED 164640 4092 168732
NET: 2983 got data
NET: 2983 onSocketFinish
NET: 2983 oSF: not ended, call shutdown()
NET: 2983 destroy undefined
NET: 2983 destroy
NET: 2983 close
NET: 2983 close handle
Error: read ECONNRESET
    at errnoException (net.js:904:11)
    at TCP.onread (net.js:558:19)

1 个答案:

答案 0 :(得分:0)

这是libuv if (stream->shutdown_req) { /* The UV_ECANCELED error code is a lie, the shutdown(2) syscall is a * fait accompli at this point. Maybe we should revisit this in v0.11. * A possible reason for leaving it unchanged is that it informs the * callee that the handle has been destroyed. */ uv__req_unregister(stream->loop, stream->shutdown_req); uv__set_artificial_error(stream->loop, UV_ECANCELED); stream->shutdown_req->cb(stream->shutdown_req, -1); stream->shutdown_req = NULL; } 中的stream->shutdown_req。我们在这里:

int uv_shutdown(

我找到了这个问题的原因:

  1. uv_shutdownuv_shutdown分配。所以有人打电话给uv_shutdown。谁致电StreamWrap::Shutdown
  2. StreamWrap::Shutdown不是一个简单的功能。见src/unix/stream.c。此函数的名称为nodejs
  3. SET_INSTANCE_METHOD("shutdown", StreamWrap::Shutdown, 0)用于shutdownwrappers/pipe_wrapwrappers/tcp_wrap方法是shutdownnodejs/lib
  4. 的一部分
  5. 所以有人从lib/net致电lib/tls。它可以是shutdownfunction onCryptoStreamFinish
  6. 因此function onSocketFinishonread ECANCELED会调用pair.encrypted.on('close', function() { process.nextTick(function() { // Encrypted should be unpiped from socket to prevent possible // write after destroy. pair.encrypted.unpipe(socket); socket.destroy(); }); });
  7. 所以你需要找到谁在你的情况下发送了关机请求。 {{1}}表示流已被杀死(例如socket1.pipe(socket2))。

    BTW我认为您可以通过使用特殊技术来解决您的问题,以便从here销毁管道套接字:

    {{1}}