犯蠢日記(一)線上環境重新 config:cache 後 .env 檔案的更改還是不生效

xinhuo發表於2018-10-31

背景

  • 本文的線上環境是本人的個人專案,非公司專案,所以一些操作很隨意。
  • 本人前幾天線上上環境配置了 OPcache 以提高效能,其中,opcache.validate_timestamps=0,因此每次更新程式碼需要手動清除 OPcache。
  • 專案快取驅動配置(CACHE_DRIVER)是預設的 file。

正文

今天就覺得檔案形式的快取不太好,快取檔案數過多,感覺快取過期了也並不會自動清理(沒去詳細瞭解),所以就考慮用 redis 來替代。

本地環境測試,更改 .env 檔案:

CACHE_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=123456
REDIS_PORT=6379

介面呼叫測試,完美,快取在 redis 裡,並且 redis 本身支援設定過期時間,過期了就自動清除了,不佔用多餘的空間。

接下來到線上配置,更改完 .env 檔案,我自然是記得需要重新快取一下配置的:

$ php artisan config:cache

好,介面呼叫測試一下。。。???不生效?!快取不在 redis 裡,依舊還是檔案快取,怎麼回事?
難道是舊的配置快取還在?沒理由啊,算了,先清除一下看看:

$ php artisan config:clear

介面呼叫測試。。。見鬼,還真可以了,算了,重新生成配置快取吧,然後可以收工了,php artisan config:cache 執行。
保險起見,再調介面測一下。。。???怎麼又不生效了??redis裡怎麼又沒有快取記錄了?見鬼了,我就不信邪了,繼續搞。

於是反反覆覆嘗試各種操作,得出結論,只要一快取了配置(config:cache 或 包含了配置快取的 optimize),.env 裡的更改就會不生效,最奇葩的是,我在本地環境裡不管我怎麼花式快取配置,也無法重現問題,一回到線上就又不行了,真是百思不得其解,到處搜尋後也沒見別人有類似情況。

冷靜了一下,決定重頭梳理一下問題:

  • .env 檔案修改了,線上環境 config:cache 後無法讀取 .env 的修改,config:clear 時才能讀取,重新 config:cache 也不行。
  • 本地無法重現問題,只線上上出現,說明問題原因可能出在本地跟線上的開發環境差異上,這就有點多了,一步步梳理。
  • 先思考 config:cache 做了什麼,才能知道什麼環境差異會有影響。
  • config:cache 應該是讀取 .env 檔案的內容後,將 config 目錄裡的所有配置檔案的 env() 呼叫都填充好,然後生成一份快取的配置檔案。。。。等等!生成的這份快取的配置檔案應該是 php 檔案!我好像知道了問題出在哪裡!

我意識到了本地環境跟線上環境的一個區別是 OPcache,線上配置了 OPcache,但是由於這次更新沒有涉及到 php檔案,所以我沒有手動清除 OPcache,問題可能就是出在這裡了。
驗證猜想:

$ php artisan opcache:clear
$ php artisan optimize
$ php artisan opcache:optimize

介面呼叫測試,終於成功了。。快取出現在 redis 裡了。。。瞬間差點被自己蠢哭,一個小小的改動都能耗費這麼長的時間,果然還是太年輕,於是決定編寫此文記錄一下自己的犯蠢時刻,保證下次不能再犯。

相關文章