奇葩的 bug 经历, nodejs 写了个库存监控工具,运行一段时间后总是卡死

364 天前
 weiwenhao

每次都是运行 10 多个小时就卡死,不退出执行,也没有错误日志。

所以打了些断点想看看卡死在哪里了,结果在非常奇怪的位置。查看内存溢出,fd 溢出等等都比较正常。stack 追踪太复杂,没找到合适的工具。

查论坛有个解决办法就是限制循环运行的次数,在运行一段时间后主动使用 process.exit 退出然后让 pm2 拉起来。

于是准备去改代码实操了,却发现之前的代码是这样的 👇


let retryCount = 4 * 60 * 60; // 基于库存检测的模式,单次耗时 3s 左右。


(async () => {
 	// ....

    // 循环检测购物车
    for (let i = 0; i < retryCount; i++) {
        // ...

        await sleep(5);
    }
})();

Σ(°ロ°),原来是我自己加了 retryCount ,但是我忘记了!!!原来卡死就是循环次数耗尽了。(另外这一段代码循环次数耗尽并不会退出会阻塞住)

2418 次点击
所在节点    Node.js
16 条回复
Belmode
364 天前
不忍直视
coderxy
364 天前
炸裂
Puteulanus
364 天前
所以这不是 bug ,这是 feature
flyqie
364 天前
所以。。楼主打算怎么 fix ?
ljtfdt
364 天前
循环次数耗尽,为什么会阻塞住呢? for 循环不是不会执行了么
weiwenhao
364 天前
@ljtfdt 不执行了,但是程序也不会退出,需要手动写 exit 进行退出,我也不太理解这个机制。
zihuyishi
364 天前
八成还是哪里有 bug ,当你不知道他为什么会阻塞住的时候说明还是哪里有问题。你可能只是找到了一个表象的 bug
weiwenhao
364 天前
@flyqie 还是要 fix 一下,退出循环之后加上一个 exit(0) 让程序主动退出,然后现在也加上了 pm2 主动拉起。
weiwenhao
364 天前
@zihuyishi 好像很有道理,为啥循环结束会阻塞是一个值得深究的问题, 我再去研究一下。
zihuyishi
364 天前
@weiwenhao 好久好久没写过 nodejs 了,不过我记得 libuv 应该是 loop 里有 callback 就不会退出循环吧。对应的就是 nodejs 如果有在运行的 Promise 就不会退出?
weiwenhao
364 天前
@zihuyishi 对的,我现在测试了一下,就是有没清理的环境,所以整个 async fn 不会退出。

(async () => {
var browser = await firefox.launch();

var context = await browser.newContext();

// await context.close(); // 这里注释就不会退出执行。
// await browser.close();

console.log("done??");
})();
gesse
364 天前
@ljtfdt
可能数据库没有关闭,就卡在那里了。
aikilan
364 天前
笑出声来 :D
liuidetmks
364 天前
数据库连接没关闭吧,
zsj1029
364 天前
请用 for await ,否则循环不会等待,一次性 100 await sleep(5)
opengg
363 天前
因为 node 在还持有 fd 或者连接,或者 event loop 未清空,或者监听了某些进程事件的时候,不会自动退出。
我曾经遇到过有个 sdk 存在未清理的 fd ,只能在代码里手动 exit()

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/994554

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX