Nodejs如何跟踪内存泄露(或者谁用过3rd-Eden/node-memcached)
Nodejs如何跟踪内存泄露(或者谁用过3rd-Eden/node-memcached)
最近加了memcached后发现线上的服务存在内存泄露,8G的内存基本跑个4,5天就吃光了,跟了几天没有什么实质进展 因为在去掉memcached后不存在内存泄露,所以怀疑是3rd-Eden/node-memcached造成的,也许是我使用方法不对。 代码比较简单
var memcached = require("memcached");
var mc = new memcached(config.memcache, {reconnect: 100, retries: 2, failures: 2, timeout: 300, failuresTimeout: 1000, minTimeout: 100, poolSize: 50});
mc.on('issue', function(details) {
//todo
});
exports.get_user = function(req, data) {
var key = data.key;
mc.get(key, function(err, item) {
if (item) {
//应用逻辑
} else {
//从数据库读取后set
//应用逻辑
}
});
}
在小访问量的情况下的确发现不了问题,用ab压测几十万条请求也没问题,内存吃个几百M基本就稳定了
但是线上环境,每台机器一天50万+的请求量,跑个4,5天内存就光了 我试过将memcache的相关代码去掉后内存不会泄露,然后只保留
var memcached = require("memcached");
var mc = new memcached(config.memcache, {reconnect: 100, retries: 2, failures: 2, timeout: 300, failuresTimeout: 1000, minTimeout: 100, poolSize: 50});
也不会泄露,
然后只将memcache的监听去掉会泄露,只将memcache的set部分去掉也会泄露,所以怀疑get在大量请求的情况下会有问题? 但看了下他代码,,,感觉无从下手。。。不知道怎么去跟踪这个问题。
Node.js 如何跟踪内存泄露(或者谁用过 3rd-Eden/node-memcached)
背景
最近在项目中引入了 memcached
后,发现线上服务存在内存泄露问题。服务器配置为 8GB 内存,运行 4 到 5 天后内存就被耗尽。初步检查发现,在移除 memcached
相关代码后,内存泄露现象消失。
疑点
怀疑是由于 3rd-Eden/node-memcached
引起的内存泄露。以下是相关代码片段:
var memcached = require("memcached");
var mc = new memcached(config.memcache, {
reconnect: 100,
retries: 2,
failures: 2,
timeout: 300,
failuresTimeout: 1000,
minTimeout: 100,
poolSize: 50
});
mc.on('issue', function(details) {
// TODO: Handle issues here
});
exports.get_user = function(req, data) {
var key = data.key;
mc.get(key, function(err, item) {
if (item) {
// 应用逻辑
} else {
// 从数据库读取后 set
// 应用逻辑
}
});
}
分析
在低访问量情况下,使用 Apache Bench (ab) 进行压测并未发现问题。但在高访问量环境下(例如每台机器每天处理 50 万以上的请求),经过 4 到 5 天内存被耗尽。进一步测试发现:
- 移除
memcached
相关代码后,内存不再泄露。 - 只初始化
memcached
客户端时,内存不泄露。 - 只有在添加
mc.get
和mc.set
操作时,内存泄露才会发生。
这表明 memcached
的某些操作可能是导致内存泄露的原因。
如何跟踪内存泄露
-
使用内存分析工具
- Node Inspector 或 Chrome DevTools: 可以帮助你找到内存泄漏的具体原因。
- Heap Snapshots: 可以捕获堆内存快照并比较它们,查看哪些对象没有被回收。
-
代码审查
- 确认是否有未释放的引用或循环引用。
- 确认是否正确关闭了
memcached
连接。
-
监控内存使用情况
- 使用
process.memoryUsage()
函数监控内存使用情况。
- 使用
示例代码:使用 Heap Snapshots 跟踪内存泄露
const memcached = require("memcached");
// 初始化 memcached 客户端
const mc = new memcached(config.memcache, {
reconnect: 100,
retries: 2,
failures: 2,
timeout: 300,
failuresTimeout: 1000,
minTimeout: 100,
poolSize: 50
});
// 启动内存监控
function startMonitoring() {
setInterval(() => {
const memoryUsage = process.memoryUsage();
console.log(`Memory Usage: ${memoryUsage.rss} bytes`);
}, 1000);
}
// 获取用户信息
exports.get_user = function(req, data) {
const key = data.key;
mc.get(key, function(err, item) {
if (err) {
console.error('Error fetching from memcached:', err);
return;
}
if (item) {
// 应用逻辑
} else {
// 从数据库读取后 set
// 应用逻辑
}
});
}
startMonitoring();
// 为了方便演示,这里模拟一些请求
for (let i = 0; i < 1000000; i++) {
exports.get_user(null, { key: `test_key_${i}` });
}
总结
通过以上步骤可以有效地追踪内存泄露问题。如果仍然无法定位问题,建议进一步检查 memcached
客户端的文档和源码,确认是否有已知的内存泄露问题。
我用这个跟踪修复了request上传超大文件的memory leak漏洞
之前碰到过node-memcached的内存泄漏,这么久了还没修
换redis试下
我跟你的情况类似,压测都没问题,线上环境就会内存溢出,我没用node-memcached这个模块,反正这些第三方的模块很多都不省心,我之前找到node-mysql可能导致内存泄露的地方https://github.com/felixge/node-mysql/issues/797,估计也有不少人掉到这坑了
你用node-heapdump把堆打出来看看
根据你的描述,你怀疑是 3rd-Eden/node-memcached
导致的内存泄漏。为了跟踪内存泄漏问题,你可以采取以下几种方法:
1. 使用内存分析工具
可以使用一些内存分析工具来帮助诊断内存泄漏问题,比如:
- MemWatchJS:用于检测Node.js中的内存泄漏。
- Heapdump:生成Node.js进程的堆快照文件,以便后续分析。
- Chrome DevTools:通过生成和分析V8引擎的堆快照来查找泄漏。
示例代码
const heapdump = require('heapdump');
const memcached = require("memcached");
var mc = new memcached(config.memcache, {reconnect: 100, retries: 2, failures: 2, timeout: 300, failuresTimeout: 1000, minTimeout: 100, poolSize: 50});
// 创建一个定时器定期生成堆快照
setInterval(() => {
heapdump.writeSnapshot('./heapdump-' + Date.now() + '.heapsnapshot', function(err, filename) {
console.log('Dump written to ' + filename);
});
}, 60000); // 每分钟生成一次堆快照
mc.on('issue', function(details) {
console.error('Memcached issue:', details);
});
exports.get_user = function(req, data) {
var key = data.key;
mc.get(key, function(err, item) {
if (err) {
console.error('Error fetching from Memcached:', err);
return;
}
if (item) {
// 应用逻辑
} else {
// 从数据库读取后set
// 应用逻辑
}
});
}
2. 监控和日志
添加更多的监控和日志输出,记录Memcached的操作和错误信息,以便更好地定位问题。
示例代码
mc.on('issue', function(details) {
console.error('Memcached issue:', details);
});
3. 检查配置参数
检查并调整 3rd-Eden/node-memcached
的配置参数,比如 poolSize
、reconnect
等,确保它们适合你的应用场景。
4. 更新库版本
检查是否有更新的库版本,新版本可能已经修复了内存泄漏问题。
总结
通过使用内存分析工具和增加监控日志,可以更有效地诊断和解决内存泄漏问题。如果你仍然无法解决问题,考虑向 3rd-Eden/node-memcached
的维护者报告问题,并提供详细的错误信息和代码片段。