Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

Node 出現 EADDRINUSE?殺程序前先證明綁定位址、監聽者與監督程式

保留完整位址與連接埠組合,在正確命名空間確認監聽者,經真正所有者停止,並驗證一次受控重啟。

Node 出現 EADDRINUSE?殺程序前先證明綁定位址、監聽者與監督程式
原創示意圖:先記錄完整綁定組合,再證明監聽者與真正所有者。 Watch at Ease

本指南把 EADDRINUSE 視為綁定所有權稽核,而不是一條「終止 Node」指令。先保存錯誤物件,再依位址、協定族與命名空間縮小衝突範圍。

接著把監聽 PID 追到真正管理它的終端、監督程式、服務或容器;只有確認 socket 已釋放,才執行一次受控重啟並用可觀察結果驗收。

1. 固定完整綁定失敗

重啟前保存 code、syscall、address、port 或 socket path,以及真實啟動命令、工作目錄、Node 版本與監督程式。EADDRINUSE 只表示本機位址已被占用,不會指出所有者。

不要把 :::3000 簡化成「3000 忙碌」。通配位址、IP 協定族與網路命名空間都是衝突條件。

2. 先讀位址與協定族,再看連接埠

Node 說明省略 host 時通常綁定 ::,否則為 0.0.0.0;許多系統的 IPv6 通配監聽也涵蓋 IPv4,因此同一連接埠仍會衝突。

比較錯誤位址與預期暴露範圍。127.0.0.1、0.0.0.0、::1、:: 不等價,不能為了消除錯誤而隨意擴大綁定或關閉 IPv6。

3. 在同一命名空間檢查監聽者

Linux 先用 ss -ltnp 或精確篩選連接埠;-l 是監聽、-n 是數字、-p 是程序。權限隱藏資訊時只增加必要的最小權限。

macOS 可用 lsof,Windows 可組合 Get-NetTCPConnection 與 Get-Process;容器情境要同時檢查主機發布端口與失敗的容器命名空間。

4. 從 PID 追到真正所有者

監聽 PID 可能只是子程序。記錄命令列與父程序,確認 nodemon、PM2、systemd、Docker Compose、Kubernetes 或 IDE 是否擁有生命週期。

nodemon 案例顯示存檔重啟也會在 :: 和 5000 衝突。應修正監督與關閉流程,不能終止所有 Node 程序。

5. 經所有者停止並驗證釋放

使用所有者正常停止:終端工作、命名 PM2 應用、systemd 單元或相關容器。先讓應用關閉 server,強制終止只在身份與範圍已證明後使用。

重跑同一檢查;成功是目標監聽消失且不被立即重生,不是停止命令有回傳。避免 killall node 和寬泛 sudo 命令。

6. 只有架構需要時才改連接埠

只有兩個預期服務需要不同端點或部署動態分配時才改端口。盲目跳號會留下舊監督程序並延後衝突。

使用端口 0 時在 listening 後讀實際位址。固定端口若屬於代理、防火牆、服務發現或健康檢查,就要更新整份契約。

7. 只重啟一次並證明監聽者

先關閉 reload 與多程序,只啟動一個實例;確認 PID/容器、位址、端口、協定族與健康路由,再恢復監督程式。

衝突復發時比較新的所有者、父程序、命名空間與時間線。乾淨 socket 後仍衝突通常是重複啟動或競態,不是快取或 Node 安裝問題。

保留完整位址與連接埠組合,在正確命名空間確認監聽者,經真正所有者停止,並驗證一次受控重啟。
原創示意圖:經監督程式或容器停止,驗證 socket 釋放後只重啟一次。 Watch at Ease