GAE - Nodejs - 一个简单的 pubsub 应用程序的内存泄漏 - 超过了软私有内存限制
Posted
技术标签:
【中文标题】GAE - Nodejs - 一个简单的 pubsub 应用程序的内存泄漏 - 超过了软私有内存限制【英文标题】:GAE - Nodejs - Memory leak for a simple pubsub app - Exceeded soft private memory limit 【发布时间】:2018-12-29 22:39:48 【问题描述】:我使用 pubsub 应用程序编写了一个简单的 appEngine。在查看 appEngine 日志时,我看到内存在不断增加和减少,并且不断重复。当我查看日志时。我收到以下错误消息。基本上我正在做的是,我已经设置了一个 cron 任务来每分钟触发这个路由,快速路由会将消息发布到 pubsub。对于这个简单的任务,我看到内存使用量持续从 89MB 增加到 131MB,并且在下一个即将到来的触发器中它失败了。请建议我如何解决此内存泄漏。
2018-07-22 10:51:00.266 IST
Exceeded soft private memory limit of 128 MB with 130 MB after servicing 9 requests total. Consider setting a larger instance class in app.yaml.
2018-07-22 10:51:00.266 IST
After handling this request, the process that handled this request was found to be using too much memory and was terminated. This is likely to cause a new process to be used for the next request to your application. If you see this message frequently, you may have a memory leak in your application or may be using an instance with insufficient memory. Consider setting a larger instance class in app.yaml.
以下是代码示例 index.js
const express = require('express');
const app = express();
const pubsub = require('./pubsub1.js');
app.get('/', (req, res) =>
res.send('Hi!');
);
app.get('/hello', (req, res) =>
var planet = req.query.planet || 'Earth';
res.send(`Hello Planet $planet!`);
);
app.get('/helloAppengineFROMcron', (req, res) =>
var message = req.query.date || 'no date';
//res.status(200).send(`Hello $name || 'World'!`);
res.send(`Hello from Express app, just triggered a pubsub messsage @ $message`);
console.log(`Hello from Express app, just triggered a pubsub messsage @ $message`);
pubsub.publishMessage('helloPubsubFROMappengine', '--> appEngine');
);
//const server = app.listen(process.env.PORT || 8080, "localhost", () =>
const server = app.listen(process.env.PORT || 8080, () =>
const host = server.address().address;
const port = server.address().port;
console.log(`Express cron http://$host:$port`);
);
pubsub1.js
//Program : pubsub1.js
// Imports the Google Cloud client library
const PubSub = require(`@google-cloud/pubsub`);
function getCurrentISTdt(format)
var cDT = new Date();
var currentOffset = cDT.getTimezoneOffset();
var ISTOffset = 330; // IST offset UTC +5:30
var ISTTime = new Date(cDT.getTime() + (ISTOffset + currentOffset)*60000);
var day = ISTTime.getDate() > 9 ? ISTTime.getDate() : '0'+ISTTime.getDate();
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var month = months[cDT.getMonth()];
var mm = (ISTTime.getMonth()+1) > 9 ? (ISTTime.getMonth()+1) : '0'+(ISTTime.getMonth()+1);
var year = ISTTime.getFullYear();
var h = ISTTime.getHours() > 9 ? ISTTime.getHours() : '0'+ISTTime.getHours();
var m = ISTTime.getMinutes() > 9 ? ISTTime.getMinutes() : '0'+ISTTime.getMinutes();
var s = ISTTime.getSeconds() > 9 ? ISTTime.getSeconds() : '0'+ISTTime.getSeconds();
var cISTdt;
if(format == "yyyymmdd")
cISTdt = year+''+mm+''+day;
else if(format == "yyyymm")
cISTdt = year+''+mm;
else if(format == "yyyy")
cISTdt = year;
else if(format == "yyyy-mmm-dd hh:mm:ss")
cISTdt = year+'-'+month+'-'+day+' '+h+':'+m+':'+s;
else if(format == "dd/mm/yyyy hh:mm:ss")
cISTdt = day+'/'+mm+'/'+year+' '+h+':'+m+':'+s;
else
cISTdt = year+'/'+mm+'/'+day+' '+h+':'+m+':'+s;
return cISTdt;
function publishMessage(topicName, data)
// [START pubsub_publish]
// [START pubsub_quickstart_publisher]
// Creates a client
const pubsub = new PubSub();
/**
* TODO(developer): Uncomment the following lines to run the sample.
*/
// const topicName = 'your-topic';
// const data = JSON.stringify( foo: 'bar' );
// Publishes the message as a string, e.g. "Hello, world!" or JSON.stringify(someObject)
data = data?data:' missed appEngine data ';
data = data + ' --> Pubsub';
const dataBuffer = Buffer.from(data);
pubsub
.topic(topicName)
.publisher()
.publish(dataBuffer)
.then(messageId =>
console.log(`Message triggered from pubsub() @ $getCurrentISTdt("yyyy-mmm-dd hh:mm:ss") - ID:$messageId published.`);
)
.catch(err =>
console.error('ERROR:', err);
);
// [END pubsub_publish]
// [END pubsub_quickstart_publisher]
//publishMessage('pubsubTest1', 'Helo Testing');
module.exports =
//functionName there : functionName here
publishMessage,
getCurrentISTdt
;
package.json
"name": "gae-hello",
"version": "1.0.0",
"description": "HelloWorlds GAE",
"main": "app.js",
"scripts":
"start": "node app.js",
"deploy": "gcloud app deploy --quiet",
"test": "echo \"Error: no test specified\" && exit 1"
,
"engines":
"node": "8.x.x"
,
"keywords": [
"express.js",
"cron",
"GAE",
"appEngine"
],
"author": "Sushanth Bobby Lloyds",
"license": "ISC",
"dependencies":
"@google-cloud/pubsub": "^0.19.0",
"express": "^4.16.3"
【问题讨论】:
after servicing 9 requests total
- 恕我直言,9 个请求不足以建立模式。我首先尝试使用更高的实例类,以检查它是否确实存在泄漏。在我的情况下(python,tho'),这个类对于我的应用程序来说太小了(垃圾收集器没有机会运行),升级类解决了这个问题。查看相关***.com/questions/35189446/…
【参考方案1】:
您可能没有遇到内存泄漏,但可能只是受到可用内存的限制。
App Engine 的默认实例类具有非常低的 RAM (128Mo)。您可以尝试将实例类增加到至少F2
:
在app.yaml
中添加以下内容:instance_class: F2
(在the docs 中阅读更多内容)
【讨论】:
以上是关于GAE - Nodejs - 一个简单的 pubsub 应用程序的内存泄漏 - 超过了软私有内存限制的主要内容,如果未能解决你的问题,请参考以下文章