不要踏到 Node.js 的黑洞陷阱 ???????? ????

也就是說, foo 變成在某種背景跑但是 foo 內的 console.

log 都沒印出來, 以致於沒發現其實在跑…www.

facebook.

com懷疑:await 會不會讓出去給別的 function 跑之後,那個 function 因某種原因會接不到 stdout?也就是我懷疑 foo 變成某種在背景跑但是 foo 內的 console.

log 不會印出來,所以會以為沒跑到懷疑:如果 function bar() 裡有個 while (1), 而當 while 裡在 await 某個 function 時, 有可能會回到 bar() 嗎?也就是跑出 while 了?這裡也做了很多嘗試,包括反覆修改 async 邏輯,但還是一直都找不出問題。還是懷疑人生好了…然後,我發現為什麼了:(黑洞:滿滿滿滿滿滿滿滿滿滿滿滿滿的 nodemon,不只一頁)htop 裡,看到滿滿滿滿的 nodemon,不知道有幾個同時在跑 (而且都沒有接到 stdout) ????????????也就是說:送端一送出 message,收端就有大量在背景偷跑的 nodemon 會瞬間收走大部份或是全部的 message而且,大量nodemon收到 message 後就會各自開始瘋狂跑 foo(),跑到 CPU, GPU 跟 RAM 都耗盡,可以持續數十分鐘所以我開始在想:nodemon 或 Node.

js 是不是在背景幫忙多開 process,因為 pm2 有這類行為。找了一些關鍵字,像是 nodejs nodemon pm2 default background process number 這些去排列組合,不過看不太出來問題所在。結果後來找到一個很關鍵的 nodemon issue:Nodemon frequently leaves the child process running (detached) · Issue #1025 · remy/nodemon重點如下:多名 nodemon user 都有發現 child process 被留在背景繼續跑(登愣!)直接用 Ctrl + c (送出 SIGINT) 來結束 nodemon 不一定有用,除非在 nodemon.

json 或 code 裡用 process.

on() 明確處理 SIGINT/SIGHUP/SIGTERM 這些 signal,不過有人用了沒效果有人 (heisian) 提出 root cause 是因為 nodemon 用了 Node.

js 的 child_process.

spawn 來建 child process,而不是用 child_process.

fork,所以 kill 了 parent 不會 kill children.

(nodemon uses child_process.

spawn instead of child_process.

fork to create child processes.

In this case, killing the parent does not kill its children.

)nodemon 作者 (remy) 回應說,因為他需要 spawn 提供的 IPC 功能,而 fork 沒有討論到一半,有人就先把他 project 用的 nodemon 幹(換)掉了…XD (改用 babel-watch )後來作者還是接受了修改的 PR (可以參考 nodemon 的 commit 62a361c, 在 2017/12/13, 重點 diff 見下圖)commit 62a361c: “fix: use fork child node processes”可是瑞凡,到了 2018 年底了還是不斷有人回報類似問題,噴到作者說請大家另外開 issue …問題查到這裡,我突然想到一句之前引起討論的話:求不要更新了,老子学不动了 ….

XDDDD (知乎討論)回頭是岸,我目前並沒有打算再花時間挖這個問題,如果有人更了解這個問題,歡迎留言指導一下 ????.( nodemon 的 Github README 有提到一些 signal 處理,也許是線索)到此,我的個人結論:我不敢用 nodemon 了Note:我用的 nodemon 版本是 1.

18.

10我只有把 nodemon 用在 dev 環境也有可能根本是我自己使用方法錯誤後來因為這個 issue 還有其他原因,我用 python 重寫了這個 service。如果還是有 nodemon 這種需求,建議可以試著確認更深的 root cause。另外,還可以比較看看 pm2, forever, node-supervisor, node-dev, babel-watch。走刻苦手工路線的話也可以用 Inotify 跟 watchdog (man) (SO1) (SO2) 自己兜 …最後,附上一張直接用 node 跑的「乾淨」 htop 圖,供參考:(正在跑的 node 跟 node 自己生出來的 thread.

)總結一下過程1.

用了 Azure Pub/Sub(還有 Queue),本來沒問題,但後來會一直收不到 message2.

發現其實有收到 message,但是印不出 log3.

發現 htop 裡有滿滿滿滿 nodemon 被留在背景跑4.

現在的 nodemon 似乎還是會有這現象5.

我逃了如果有寫錯或是需要更新的,歡迎在留言提醒我~ ????非常感謝 幾位好友幫忙 review 了這篇文章 (A-Z):黃焌華 / Clyde Wu / Fischer Liu / gasolin / John Hu / kcliu / Luke Chang / Paul Yang / Ricky Chien / Sean Lee / Yu-Jen Chang一些關於我的資訊:關於我。 (Will Wang / IKARi)我是軟體工程師,目前在 Linker Networks 開發 AI 相關的產品。medium.

com.. More details

Leave a Reply