V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
weiwenhao
V2EX  ›  Node.js

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

  •  
  •   weiwenhao · 156 天前 · 2138 次点击
    这是一个创建于 156 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    
    let retryCount = 4 * 60 * 60; // 基于库存检测的模式,单次耗时 3s 左右。
    
    
    (async () => {
     	// ....
    
        // 循环检测购物车
        for (let i = 0; i < retryCount; i++) {
            // ...
    
            await sleep(5);
        }
    })();
    
    

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

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

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

    var context = await browser.newContext();

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

    console.log("done??");
    })();
    gesse
        12
    gesse  
       156 天前
    @ljtfdt
    可能数据库没有关闭,就卡在那里了。
    aikilan
        13
    aikilan  
       156 天前
    笑出声来 :D
    liuidetmks
        14
    liuidetmks  
       156 天前
    数据库连接没关闭吧,
    zsj1029
        15
    zsj1029  
       156 天前
    请用 for await ,否则循环不会等待,一次性 100 await sleep(5)
    opengg
        16
    opengg  
       156 天前 via Android
    因为 node 在还持有 fd 或者连接,或者 event loop 未清空,或者监听了某些进程事件的时候,不会自动退出。
    我曾经遇到过有个 sdk 存在未清理的 fd ,只能在代码里手动 exit()
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5325 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 07:30 · PVG 15:30 · LAX 00:30 · JFK 03:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.