data-id="1190000004975909" data-licence="">
昨晚線上出故障,緊急處理切換容災後緩解了故障,解決故障後從容災切換回正式服務時發現PHP檔案更新無效,重啟FPM後才生效。以下記錄複盤追查的過程。
因為是PHP檔案更新不生效,所以馬上懷疑到opcache上面,到線上看了一眼php.ini,果然使用了opcache,並且檢測間隔時間設定為60秒。查看昨晚的日誌,更新不生效持續時間遠大於60秒,所以這個檢測間隔時間的問題可以PASS了,我們繼續。
在線上環境查看更新的文件和日誌中的時間的時候,突然發現PHP文件時間和日誌中的時間對應不上,馬上找OP確認,OP交待說這個文件是回滾mv回來的,所以文件時間和我預期的不一致。我用stat指令看了一下,果然modify time相比access time早了一段時間,依據這點線索推測opcache依靠的是PHP檔案的modify time作為檔案被修改的偵測條件。在線下復現問題,填坑成功!
下面總結一下填坑過程中查的一些相關的知識點
加載opcache
在php.ini中增加opcache時需要使用zend_extension,而不是extension,不然會得到以下WARNING
rrrereee使用下列建議設定來獲得較好的效能:
<code>PHP Warning: PHP Startup: Invalid library (appears to be a Zend Extension, try loading using zend_extension=opcache.so from php.ini) in Unknown on line 0</code>
本次涉及到的有兩個參數
revalidate_freq,預設2
檢查腳本時間戳是否有更新的週期,以秒為單位。 設定為 0 會導致針對每個要求, OPcache 都會檢查腳本更新
validate_timestamps,預設1
系統指令和函數stat
access time 表示我們最後一次存取檔案的時間
modify time 表示我們最後一次修改檔案的時間change time 表示我們最後一次對檔案屬性改變的時間,包括權限,大小,屬性等等
C/C++中也可以使用stat方法查詢檔案的這3個時間屬性,一般應用都會透過modify time判斷檔案是否更新,我們這次踩坑就是因為檔案是mv操作的,modity time沒有更新,所以opcache沒有更新。
以上就介紹了opcache的偵測檔案更新的小坑,包含了cache方面的內容,希望對PHP教學有興趣的朋友有幫助。