部署到Bluemix的简单node.js应用程序似乎正在泄漏内存

时间:2015-06-04 13:49:11

标签: node.js memory-leaks ibm-cloud

我正在学习node.js,并且有一个相当简单的应用程序,在部署到Bluemix时似乎泄漏了内存。我需要帮助确定这是由我的代码还是我正在使用的模块引起的。

当使用Monitoring and Cloudant服务进行部署时,它会因内存不足而崩溃,并且每隔12-14小时由Bluemix重新启动 - 具有256兆内存。我将RAM增加到1 gig并且它仍然会发生(尽管不那么频繁)。

当我将应用程序部署到Bluemix并向/ route发出调用时,我可以看到内存缓慢上升。在Windows中本地测试时,我看不到相同的行为(通过进程资源管理器测试并查看专用字节数和工作集)

我已经简化了我的应用程序(并删除了监控服务)并且仍然可以重现,尽管使用简化的应用程序增加速度较慢。

/*jshint node:true*/

//------------------------------------------------------------------------------
// app.js - Middleware routing
//------------------------------------------------------------------------------

// This application uses express as it's web server
// for more info, see: http://expressjs.com
var express = require( 'express' );

// For handling the POST bodies and multi-part bodies0
var bodyParser = require( 'body-parser' );
var multer = require( 'multer' );

// Create a new express server
var app = express();

// Get the app environment from Cloud Foundry
var cfenv = require( 'cfenv' );
var appEnv = cfenv.getAppEnv();

// Catch all handlers for unhandled URLs
//
app.post( '/*', function( req, res ){
    logRequest( req );
    res.send( 'Unhandled POST received' );
});

app.get( '/*', function( req, res ){
    logRequest( req );
    res.send( 'Unhandled GET received' );
});


// start server on the specified port and binding host
app.listen(appEnv.port, appEnv.bind, function() {

    // print a message when the server starts listening
  console.log("server starting on -- " + appEnv.url);
});

function logRequest(req){
    console.log("Received,"+new Date().toLocaleString()+","+req.method+","+req.originalUrl);
}

这是我收集的数据,内存列在Megs中,我向/ route发出了请求:

  • 启动时为83.1M
  • 一次调用/
  • 后的83.5M 再次打电话给/ 之后,
  • 83.5M
  • 83.6再打五次电话后
  • 84.2再打电话给/
  • 85.1再拨打10次/
  • 之后
  • 86.6再打电话给/

我尝试使用heapdump模块,但在部署到Bluemix时失败。

cf-node-debug安装现已成功 - 请参阅问题底部 按照建议安装cf-node-debug,在package.json中指定:

  "scripts": {
    "start": "node_modules/.bin/cf-node-debug app.js"
  },

当我推送应用程序时,我得到以下内容:

T13:19:44.08-0400 [STG/39]     OUT -----> Downloaded app package (36K)
T13:19:44.46-0400 [STG/39]     OUT -----> Downloaded app buildpack cache (2.6M)
T13:19:44.80-0400 [STG/0]      OUT     -----> Node.js Buildpack Version: v1.18-20150519-1759
T13:19:44.85-0400 [STG/0]      OUT -----> Resetting git environment
T13:19:45.35-0400 [STG/0]      OUT        TIP: Specify a node version in package.json
T13:19:45.35-0400 [STG/0]      OUT -----> Defaulting to latest stable node: 0.12.2
T13:19:45.35-0400 [STG/0]      OUT -----> Installing IBM SDK for Node.js from cache
T13:19:45.78-0400 [STG/0]      OUT -----> Checking and configuring service extensions
T13:19:45.95-0400 [STG/0]      OUT -----> Restoring node_modules directory from cache
T13:19:46.21-0400 [STG/0]      OUT -----> Pruning cached dependencies not specified in package.json
T13:19:47.22-0400 [STG/0]      OUT -----> Installing dependencies
T13:19:54.50-0400 [STG/0]      OUT        > ws@0.4.32 install /tmp/staged/app/node_modules/cf-node-debug/node_modules/node-inspector/node_modules/ws
T13:19:54.50-0400 [STG/0]      OUT        > (node-gyp rebuild 2> builderror.log) || (exit 0)
T13:20:04.31-0400 [STG/0]      OUT        make: Entering directory `/tmp/staged/app/node_modules/cf-node-debug/node_modules/node-inspector/node_modules/ws/build'
T13:20:04.32-0400 [STG/0]      OUT          CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
T13:20:04.71-0400 [STG/0]      OUT          SOLINK_MODULE(target) Release/obj.target/bufferutil.node
T13:20:04.76-0400 [STG/0]      OUT          SOLINK_MODULE(target) Release/obj.target/bufferutil.node: Finished
T13:20:04.77-0400 [STG/0]      OUT          COPY Release/bufferutil.node
T13:20:04.78-0400 [STG/0]      OUT          CXX(target) Release/obj.target/validation/src/validation.o
T13:20:05.15-0400 [STG/0]      OUT          SOLINK_MODULE(target) Release/obj.target/validation.node
T13:20:05.21-0400 [STG/0]      OUT          SOLINK_MODULE(target) Release/obj.target/validation.node: Finished
T13:20:05.21-0400 [STG/0]      OUT          COPY Release/validation.node
T13:20:05.24-0400 [STG/0]      OUT        make: Leaving directory `/tmp/staged/app/node_modules/cf-node-debug/node_modules/node-inspector/node_modules/ws/build'
T13:20:05.29-0400 [STG/0]      OUT        npm WARN deprecated static-favicon@1.0.2: use serve-favicon module
T13:20:05.80-0400 [STG/0]      OUT        cf-node-debug@0.1.2 node_modules/cf-node-debug
T13:20:05.80-0400 [STG/0]      OUT        ├── underscore@1.6.0
T13:20:05.80-0400 [STG/0]      OUT        ├── q@1.0.1
T13:20:05.80-0400 [STG/0]      OUT        ├── passport-local@1.0.0 (passport-strategy@1.0.0)
T13:20:05.80-0400 [STG/0]      OUT        ├── nopt@2.2.1 (abbrev@1.0.7)
T13:20:05.80-0400 [STG/0]      OUT        ├── passport@0.2.2 (pause@0.0.1, passport-strategy@1.0.0)
T13:20:05.80-0400 [STG/0]      OUT        ├── client-sessions@0.6.0 (cookies@0.3.8)
T13:20:05.80-0400 [STG/0]      OUT        ├── http-proxy@1.1.6 (eventemitter3@1.1.0)
T13:20:05.80-0400 [STG/0]      OUT        ├── body-parser@1.3.1 (raw-body@1.1.6, qs@0.6.6, bytes@1.0.0, type-is@1.2.1)
T13:20:05.80-0400 [STG/0]      OUT        ├── express@4.4.5 (parseurl@1.0.1, utils-merge@1.0.0, merge-descriptors@0.0.2, cookie@0.1.2, escape-html@1.0.1, qs@0.6.6, cookie-signature@1.
@1.0.0, fresh@0.2.2, vary@0.1.0, methods@1.0.1, serve-static@1.2.3, buffer-crc32@0.2.3, path-to-regexp@0.1.2, type-is@1.2.1, accepts@1.0.7, proxy-addr@1.0.1, debug@1.0.2, send@0.4.3)
T13:20:05.80-0400 [STG/0]      OUT        ├── cfenv@0.2.0 (ports@1.1.0, js-yaml@3.0.2)
T13:20:05.80-0400 [STG/0]      OUT        ├── handlebars@2.0.0 (optimist@0.3.7, uglify-js@2.3.6)
T13:20:05.80-0400 [STG/0]      OUT        └── node-inspector@0.7.3 (opener@1.3.0, debug@0.8.1, which@1.0.9, async@0.4.1, strong-data-uri@0.1.1, yargs@1.1.3, rc@0.3.5, glob@3.2.11, exp
4.32)
T13:20:06.02-0400 [STG/0]      OUT -----> Caching node_modules directory for future builds
T13:20:06.59-0400 [STG/0]      OUT -----> Cleaning up node-gyp and npm artifacts
T13:20:06.60-0400 [STG/0]      OUT -----> No Procfile found; Adding npm start to new Procfile
T13:20:06.60-0400 [STG/0]      OUT -----> Building runtime environment
T13:20:06.60-0400 [STG/0]      OUT -----> Checking and configuring service extensions
T13:20:06.85-0400 [STG/0]      OUT -----> Installing App Management
T13:20:06.90-0400 [STG/0]      OUT -----> WARN: App Management (Development Mode) cannot be installed because the start script cannot be found.
T13:20:06.91-0400 [STG/0]      OUT        TIP: Specify your start script in 'package.json' or 'Procfile'.
T13:20:06.92-0400 [STG/0]      ERR
T13:20:11.28-0400 [STG/39]     OUT -----> Uploading droplet (20M)
T13:20:20.47-0400 [DEA/39]     OUT Starting app instance (index 0) with guid 1dde346e-4e51-407f-af7b-607772826e72
T13:20:32.91-0400 [App/0]      OUT
T13:20:32.91-0400 [App/0]      OUT > NodejsStarterApp@0.0.1 start /home/vcap/app
T13:20:32.91-0400 [App/0]      OUT > cf-node-debug app.js
T13:20:33.38-0400 [App/0]      ERR     util.js:634
T13:20:33.38-0400 [App/0]      ERR   ctor.prototype = Object.create(superCtor.prototype, {
T13:20:33.38-0400 [App/0]      ERR                                           ^
T13:20:33.38-0400 [App/0]      ERR TypeError: Cannot read property 'prototype' of undefined
T13:20:33.38-0400 [App/0]      ERR     at Object.exports.inherits (util.js:634:43)
T13:20:33.38-0400 [App/0]      ERR     at Object.<anonymous> (/home/vcap/app/node_modules/cf-node-debug/node_modules/http-proxy/lib/http-proxy/index.js:106:17)
T13:20:33.38-0400 [App/0]      ERR     at Module._compile (module.js:460:26)
T13:20:33.38-0400 [App/0]      ERR     at Object.Module._extensions..js (module.js:478:10)
T13:20:33.38-0400 [App/0]      ERR     at Module.load (module.js:355:32)
T13:20:33.38-0400 [App/0]      ERR     at Function.Module._load (module.js:310:12)
T13:20:33.38-0400 [App/0]      ERR     at Module.require (module.js:365:17)
T13:20:33.38-0400 [App/0]      ERR     at require (module.js:384:17)
T13:20:33.38-0400 [App/0]      ERR     at Object.<anonymous> (/home/vcap/app/node_modules/cf-node-debug/node_modules/http-proxy/lib/http-proxy.js:4:17)
T13:20:33.38-0400 [App/0]      ERR     at Module._compile (module.js:460:26)
T13:20:33.40-0400 [App/0]      ERR npm ERR! Linux 3.13.0-39-generic
T13:20:33.40-0400 [App/0]      ERR npm ERR! argv "/home/vcap/app/vendor/node/bin/node" "/home/vcap/app/vendor/node/bin/npm" "start"
T13:20:33.40-0400 [App/0]      ERR npm ERR! node v0.12.2
T13:20:33.40-0400 [App/0]      ERR npm ERR! npm  v2.7.4
T13:20:33.40-0400 [App/0]      ERR npm ERR! code ELIFECYCLE
T13:20:33.40-0400 [App/0]      ERR npm ERR! NodejsStarterApp@0.0.1 start: `cf-node-debug app.js`
T13:20:33.40-0400 [App/0]      ERR npm ERR! Exit status 1
T13:20:33.40-0400 [App/0]      ERR npm ERR!
T13:20:33.40-0400 [App/0]      ERR npm ERR! Failed at the NodejsStarterApp@0.0.1 start script 'cf-node-debug app.js'.
T13:20:33.41-0400 [App/0]      ERR npm ERR! This is most likely a problem with the NodejsStarterApp package,
T13:20:33.41-0400 [App/0]      ERR npm ERR! not with npm itself.
T13:20:33.41-0400 [App/0]      ERR npm ERR! Tell the author that this fails on your system:
T13:20:33.41-0400 [App/0]      ERR npm ERR!     cf-node-debug app.js
T13:20:33.41-0400 [App/0]      ERR npm ERR! You can get their info via:
T13:20:33.41-0400 [App/0]      ERR npm ERR!     npm owner ls NodejsStarterApp
T13:20:33.41-0400 [App/0]      ERR npm ERR! There is likely additional logging output above.
T13:20:33.41-0400 [App/0]      ERR npm ERR! Please include the following file with any support request:
T13:20:33.41-0400 [App/0]      ERR npm ERR!     /home/vcap/app/npm-debug.log
T13:20:33.47-0400 [DEA/39]     ERR Instance (index 0) failed to start accepting connections


$ npm --version
1.4.28  
$ node --version  
v0.10.33

看起来像http-proxy@1.1.6(eventemitter3@1.1.0)

注意:使用SDK for IBM的Node.js

在杰克的建议下,我尝试指定引擎,如:

  "engines": {
    "node": "0.10.x",
    "npm": "2.7.4"
  },

分段报告:

2015-06-04T14:27:41.87-0400 [STG/0]      OUT -----> Resetting git environment
2015-06-04T14:27:42.31-0400 [STG/0]      OUT -----> Requested node range:  0.10.x
2015-06-04T14:27:42.31-0400 [STG/0]      OUT -----> Resolved node version: 0.10.38
2015-06-04T14:27:42.31-0400 [STG/0]      OUT -----> Installing IBM SDK for Node.js from cache

但我得到了和以前一样的错误:

2015-06-04T14:28:12.89-0400 [App/0]      ERR util.js:556
2015-06-04T14:28:12.89-0400 [App/0]      ERR   ctor.prototype = Object.create(superCtor.prototype, {
2015-06-04T14:28:12.89-0400 [App/0]      ERR                                           ^
2015-06-04T14:28:12.89-0400 [App/0]      ERR TypeError: Cannot read property 'prototype' of undefined

更新美国东部时间下午3:35

我分叉cf-node-debug并将http-proxy修改为1.11.x.我将package.json更新为:

"cf-node-debug": "git://github.com/retinaburn/cf-node-debug.git",

我推送了应用程序,现在可以访问调试控制台了,但似乎没有任何可用于调查内存泄漏的堆转储。

2 个答案:

答案 0 :(得分:1)

您可能想要隔离您的问题。在本地运行应用程序时是否会发生此行为? 有一个很好的节点模块memwatch可能会有所帮助。 我认为memwatch适用于node.js 10.x. 有一个memwatch-next可用于node.js 0.12.x。

答案 1 :(得分:0)

我已确认指定的示例应用程序确实在Bluemix中执行垃圾收集,并将内存设置为1gb。

我使用apache bench测试了对10个并发事务的'/'的1000个请求。

我怀疑早期的体积测试太低而无法触发gc。