隨機埠生成器
在任意範圍內生成隨機 TCP 或 UDP 埠號,自動跳過知名服務和常被佔用的埠,避免本地服務衝突。
一個你機器上別人多半不會來搶的埠號。 選擇需要多少個埠以及抽取的範圍。預設會跳過知名服務所佔用的埠,因此得到的號碼不太可能與已在執行的程式衝突。
在任意範圍內生成隨機 TCP 或 UDP 埠號,自動跳過知名服務和常被佔用的埠,避免本地服務衝突。
一個你機器上別人多半不會來搶的埠號。 選擇需要多少個埠以及抽取的範圍。預設會跳過知名服務所佔用的埠,因此得到的號碼不太可能與已在執行的程式衝突。
TCP 或 UDP 埠是一個 16 位數字,可用範圍為 0 到 65535。IANA 把這個空間分成三段。0 到 1023 是系統埠或知名埠,保留給 HTTP 的 80、SSH 的 22 等標準服務;在類 Unix 系統上繫結其中之一通常需要 root 許可權或顯式的 capability。1024 到 49151 是註冊埠,按申請分配給特定應用,PostgreSQL 的 5432 和 MySQL 的 3306 就在這一段。49152 到 65535 是動態埠或臨時埠範圍,保留給客戶端的臨時分配。
對本地開發服務而言,最合適的位置是 1024 以上的註冊埠段,既避開特權段也避開臨時埠段。這正是本生成器把下界預設設為 1024 的原因。保持在 49152 以下比聽上去更重要:每當程式發起對外連線時,作業系統都會從臨時埠範圍中取號,因此停放在那裡的服務重啟後可能發現埠已被佔用。
僅靠隨機並不能避免衝突。一次隨機抽取完全可能落在 3306、5432、6379 或 8080 上,而在一臺正常工作的開發機上,這些恰恰是最可能已被佔用的號碼。這裡使用的跳過列表覆蓋了經典 Unix 服務、常見資料庫與訊息中介軟體,以及流行框架的預設埠,例如 Node 工具鏈的 3000 和本地 HTTP 伺服器的 8000、8080。
跳過它們的代價幾乎為零——候選池裡仍有數萬個號碼——卻能消除「埠已被佔用」這類報錯最常見的來源。如果你確實想要其中某個號碼,關閉該選項即可恢復完整範圍。
請注意這只是機率上的輔助,而不是預留。本工具無法檢查你的機器,也就無從得知是否有程式正在監聽。要確認埠確實空閒,請在本地檢查:macOS 或 Linux 用 lsof -i :埠,較新的 Linux 用 ss -ltnp,Windows 用 netstat -ano | findstr :埠。
容器和 CI 環境會改變這套演算法。容器內部的埠空間通常是私有的,因此兩個容器可以同時監聽 8080 而互不衝突;衝突風險轉移到宿主機一側,那裡釋出出來的埠共享同一個名稱空間。隨機選一個宿主埠並對映到固定的容器埠,是並排運行同一服務多個副本的常見做法。
許多 CI 系統和編排工具用另一種方式解決問題:直接向內核要一個空閒埠——繫結到埠 0,作業系統會分配一個未被使用的埠並告訴你選中了哪個。這種方式沒有競態且永遠正確,因此當你的程式可以在執行時被告知埠時應優先採用。而像這裡生成的固定號碼,則適合在任何程式啟動之前,需要把一個穩定值寫進配置檔案、docker-compose 對映或團隊文件的場景。