Opcache 的執行流程大致如下,
Opcache 的目地是避免重複編譯,減少 CPU 和記憶體開銷。
由於這篇文章的本意是想記錄以及備註一下開啟 opcache 後出現的一些問題,所以這篇文章不會記錄如何安裝 opcache 以及如何配置,推薦這篇文章大家參考一下就可以了,配置說的都很明確了。
正文
在配置中有 2 個配置很重要,需要重點關注
opcache.validate_timestamps=0;
opcache.revalidate_freq=60;
validate_timestamps
用於驗證是否要重新生成快取指令碼, 如果設定為 0(效能最佳),需要手動在每次 PHP 程式碼更改後手動清除 OPcache。 如果此值為 0,那麼 revalidate_freq
將失去作用。
revalidate_freq
用於控制 opcache 多久生成一次快取位元組碼,預設 60s。所以一般我們在開發環境中將上面兩個值配置為
opcache.validate_timestamps=1;
opcache.revalidate_freq=1;
或者乾脆直接關閉 opcache。
上面提到了,如果將 validate_timestamps
配置為 0 以後,我們每次部署 PHP 的時候預設是不會自動生成快取。這句話其是是不嚴謹的,因為部署 PHP 的時候有兩種方式,一種是直接覆蓋就檔案,另一種是使用 CI 釋出會自動生成新的部署目錄,並通過軟連線的方式指定到 web 目錄
如果是第一種部署方式的話,opcache 確實不會自動生成快取,因為 opcache 通過檔案的真實路徑進行快取,如果檔案存在就不會再次快取,也就導致了部署後線上並沒有看到新的功能程式碼。
而另一種方式的確會主動生成快取,因為上面說了,opcache 是通過檔案的真實路徑進行快取的,這就導致了每次部署都會生成快取位元組碼,那麼就導致了舊的快取沒有被清理,那麼遲早有一天會撐爆記憶體。
所以,在部署程式碼的時候如何清理 opcahce 生成的快取就成為了關鍵所在。
解決方案
通過搜尋實踐發現了幾種方式,分別為
- 平滑重啟 php-fpm
- 通過 opcache_reset () 函式
- 第三方庫
平滑重啟的方式就類似下面這樣,通過部署鉤子實現
cd /www/myproject
sudo -u www git reset --hard
sudo -u www git pull origin master
sudo -u root /etc/init.d/php-fpm-73 reload
使用 opcache_reset () 函式需要注意的問題就是在 cli 命令列下執行此函式並不能清理 php-fpm 下生成的快取位元組碼,所以可以通過一種曲線救國的方式
curl http://example.com/op.php
這個 op.php
檔案裡面就專門執行 opcache_reset () 函式,但是這種方式總感覺有點怪怪的。
通過第三方庫 (推薦) 的方式,大佬推薦 cachetool
本作品採用《CC 協議》,轉載必須註明作者和本文連結