故障排除策略 本頁面提供了一個通用且有條理的框架,用於在*不使用人工智慧(AI)*的情況下,自行解決在使用 Caddy 時可能遇到的大多數問題。當你在論壇尋求幫助時,我們也建議採取類似的步驟。在許多情況下,透過一些批判性思考,你就能回答自己的問題或解決遇到的困擾。 你知道什麼? 你可能不知道問題是什麼、是由什麼引起的,或者如何修復它,所以讓我們從一些你肯定知道的基本事項開始: 你的預期 大聲說出來,或在腦海中思考,或者將其寫/打下來。請務必清晰且具體,不留任何疑問或模糊空間。你甚至可以向自己解釋為什麼那是你的預期。 「它應該能運作」並不是一個好的預期。 「當我向這個 URI 發送請求時,我預期會得到一個 301 重定向」則好得多。 目前的行為 觀察發生了什麼事。究竟發生了什麼,它與你的預期有何不同?綜合你所知道的一切。 「它壞了」或「沒反應」這類說法既無助又懶惰;除了作為對已詳細記錄的特定行為的簡短描述外,請在任何地方都避免使用這類詞彙。 「我得到的不是 301 響應,而是 200 響應,雖然我確實看到了 Server: Caddy 標頭,」這樣說就好得多,因為它對比了現狀與你的預期,並綜合了其他已知資訊,這告訴我們請求至少已經到達了 Caddy 實例。 日誌 Caddy 的日誌中寫了什麼?預設情況下,這些日誌會寫入啟動該程序(process)的終端機。如果是以「分離(detached)」模式運行(例如作為系統服務),你可能需要從其他地方獲取日誌。 請注意,HTTP 請求日誌(「訪問日誌/access logs」)與程序日誌不同,需要在設定中明確啟用。 如果你還沒有啟用,可能也會想要啟用 DEBUG 級別的日誌。 但無論如何,你首先應該做的事情之一就是查看日誌。*查看所有的日誌。*訊息的上下文很重要,因此孤立的一行日誌很少有用。收集比你認為需要的更多的資訊,並在整個故障排除過程中保留它們。 日誌中是否有任何提示? 識別並懷疑假設 在進一步討論之前,我們必須強調:審視你的假設至關重要。我們都會根據習慣和預期做出假設。「留意你的假設,你的力量將會變得強大。」(——尤達,或者是類似的人說過的話。) 例如,一個常見的假設是:在重新編譯 Caddy 之後,執行 caddy 將會執行新的程式碼。這只有在你的編譯二進制文件替換了 $PATH 中的文件時才成立。實際上,通常應該使用 ./caddy 來調用。 隨著你的部署或配置變得越來越複雜,假設也會層層堆疊。例如,在 Docker 中部署涉及重新構建映像並執行它,這會使你可能做出的假設倍增。 許多問題和錯誤報告最終被發現是外部系統和網絡配置的問題,而不是 Caddy 本身。例如,如果你無法連接到你的 Caddy 實例,但 Caddy 明顯正在運行,你可能會假設這不是 DNS 的問題。提示:這幾乎總是 DNS 的問題。 甚至只是假設你已經重載(reload)了配置,但實際上並沒有,這也是一個常見的錯誤。努力讓你的流程保持嚴謹。在每個層級進行驗證。 重現行為 這是一個關鍵步驟,通常會讓問題自行解決:讓問題再次發生。 具體來說,是以盡可能精簡的方式讓它再次發生。排除不必要的配置、部署步驟、環境因素等,直到問題消失。 一個常見的策略是每次只排除一件事,然後重試,直到問題消失。那麼你移除的那件事很可能就是原因,或者——這也是懷疑假設的好地方——最後移除的那件事與之前移除的東西的某種組合才是原因。透過重新加入最初移除的東西來進行驗證。縮小範圍。 另一個想法是每次迭代排除約一半的內容,一旦問題消失,再排除剩下那一半的一半,依此類推。這就像二分搜尋法(binary search),速度可能會更快。 或者,你也可以反轉這些策略,不要使用排除法,而是從零開始逐步構建你的配置或場景,每次重試,直到問題出現。 通常,單單這個過程就能識別出問題,修復方法也會變得顯而易見。如果還沒有,你至少可以記錄下重現問題的最簡步驟。 探索行為 掌握了重現問題的步驟後,你就具備了診斷原因的有利條件。這涉及反覆嘗試,如果你精通技術,還可以閱讀程式碼。 如果你無法解釋為什麼會發生問題,請改變行為。做一個微小的改動然後重試。例如,如果你的相關配置涉及正則表達式,請更改/簡化該表達式——或者完全移除它——看看是否能做點什麼來獲得你想要的行為。即使結果不是你想要的,至少你知道問題出在正則表達式或配置上。 在探索時,注意哪些有效、哪些無效的模式。這應該會引導你找到解決方案。 如果你找到了解決方案,那麼你可以決定這是否應該被視為一個 Bug。有時這並不明確;無論如何,都可以將你的實驗過程發布為一個 issue,並獲取維護者的反饋。 如果這不是一個 Bug,恭喜你!你解決了一個問題,並在此過程中至少學到了一些東西。 考慮在論壇中分享你的經驗,以幫助其他可能遇到相同問題的人。