事情是這樣的,總所周知,因為我的主要博客每次構建的時候會涉及到一些動態內容以及優化,所以它是被 host 在 ZEIT 的伺服器上。具體來說,在構建的時候我會通過腳本啟動一個本地 NodeJS
伺服器,然後 Jekyll
通過 RPC 來調用指令或的結果。我隨機給 NodeJS
伺服器設置了一個 5001
端口,然後這樣的配置也一直穩定運行了一年多。
然後,從大概一年前開始,ZEIT 會隨機對博客的構建過程報錯,內容是 HTTP 請求不能發往 HTTPS 伺服器。我傻了,一是我的 NodeJS 伺服器就是 HTTP 伺服器,二是本來這就是構建過程中的本地臨時伺服器,上線後這個伺服器就被關閉了,好像並沒有用 HTTP 的必要?但這些都不是重點,重點是博客沒有通過通過構建正確上線了,於是我開始排查原因。我首先想的是是不是 Express
因為某種原因強行默認 HTTPS 設置,雖然這從道理上講不太可能,但是現在軟體為了安全性其實什麼都可能做得出來。但我調研後發現並沒有這樣的事情。然後我就在想是不是 ZEIT 為了安全默認把所有 HTTP 連接都代理成 HTTPS,包括內部連接。
於是在我準備給 ZEIT 工程師發郵件之前,我準備做一個最小可復現專案來為我的郵件提供論點支撐。OK,最詭異的事情發生了,我做不出這樣的一個穩定復現的最小專案。同樣的配置,同樣的版本,在我的博客構建過程中就會報錯,但我新開一個專案就沒有任何問題。再加上我博客構建的報錯也不是穩定觸發的,一開始只有 10% 的幾率觸發,到後來慢慢變大到 90% 的幾率觸發,但都不是 100%。到這個時候我已經有點崩潰了。
於是我還是給 ZEIT 工程師發了一個郵件,他告訴我應該不是 ZEIT 的問題,是我自己的問題。我覺得也是可信的,要不然同時以 ZEIT 為提供商的眾多開源專案主頁以及甚至許多商業專案早就給 ZEIT 發律師函了。所以我開始對我的代碼做詳細的審計。其實在開啟 NodeJS
服務部分代碼不多,只有不到 50 行,但我翻來覆去看了好久,始終沒有發現任何問題。況且根據報錯伺服器應該是被成功啟動了的,只是不知道為什麼只接受 HTTPS 請求。但我在伺服器端明明白白是啟動了一個 HTTP 伺服器,到底為什麼他會最後變成一個 HTTPS 伺服器?再加上開啟伺服器的過程是在我博客構建的最後階段,之前會有大概 10 分鐘的依賴安裝,前戲等等。也就是說我每一次 Debug,就算我就改了一個字符,也要等至少 10 分鐘才能看到結果。我真的要被搞崩潰了。
再無數次試錯後(因為我根本不知道錯在哪),我腦筋突然不知道怎麼了,把端口號從 5001
改成 4001
。然後,構建成功了。。。
也就是說,其實我的伺服器一直都沒有啟動成功,而是 ZEIT 有一個 5001
的服務一直在運行。。。而不知為什麼,我的伺服器啟動腳本也沒有報啟動失敗端口佔用的錯誤。
但問題是,為什麼 5001
端口被佔用沒有寫在文件裡呢?我保證我全網都沒有搜到 ZEIT 會佔用 5001
端口的信息,而且還是隨機佔用?有的時候佔用,有的時候不佔用?
於是,這個困擾了我快一年的問題,就換了一個端口後,解決了。。。