[英]When exactly does PHP 5.5+ Opcache check file timestamp based on revalidate_freq setting
在此之前/其他地方已經提出道歉,但我找不到答案。
我們在部署后的一分鍾內遇到了一些問題,我們認為它們與Opcache有關。 在我們的實時設置中,我們有以下Opcache設置:
opcache.revalidate_freq=60
opcache.validate_timestamps=1
PHP做了以下哪些操作?
當PHP需要一個文件時,它是否在那一點上檢查它自上次生成文件的新緩存以來是否已經過60秒,如果它已經更多,那么為此請求生成一個新緩存?
或者它是否在某種形式的計時器(或其他)上運行,其中60秒與上次需要文件時無關?
我期待選項1,但這不能解釋我們60秒左右的問題,因為文件的文件路徑不同,因為我們每次都部署到交替的A或B目錄。
我希望這是有道理的? 謝謝你的幫助。
基於我對PHP源代碼的分析,類似於選項1的是發生的事情。 當PHP需要一個文件時, 它會檢查自上次編譯或重新驗證文件以來它是否為opcache.revalidate_freq
秒 。 如果沒有,它會跳過重新驗證(時間戳檢查)。
換句話說, opcache.revalidate_freq
設置指定時間戳檢查的最大頻率。 在請求之前,文件不會被重新驗證 ,即使自上次重新驗證以來已經過了一年。
這是ZendAccelerator.c中處理緩存驗證的C函數 :
int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle)
{
if (persistent_script->timestamp == 0) {
return SUCCESS; /* Don't check timestamps of preloaded scripts */
} else if (ZCG(accel_directives).revalidate_freq &&
persistent_script->dynamic_members.revalidate >= ZCG(request_time)) {
return SUCCESS;
} else if (do_validate_timestamps(persistent_script, file_handle) == FAILURE) {
return FAILURE;
} else {
persistent_script->dynamic_members.revalidate = ZCG(request_time) + ZCG(accel_directives).revalidate_freq;
return SUCCESS;
}
}
當成功重新驗證腳本時 - 也就是說,當PHP檢查文件的時間戳並發現自文件放入緩存后它沒有更改時,它會將該文件標記為另一個opcache.revalidate_freq
秒的“新鮮”( .revalidate
屬性)。 這將阻止在該時間段內進一步的時間戳檢查(PHP將假定文件是新鮮的)。
如果重新驗證不成功 - 即時間戳比緩存中的更新,則會導致重新編譯,這也會設置相同的.revalidate
屬性(這在上面的代碼中沒有顯示),再次免除了文件的重新驗證。同期。
上面的函數似乎只能從persistent_compile_file()
調用,這是一個在執行腳本時調用的函數。 我找不到任何其他引用它會指示使用另一個觸發器,例如計時器。
所以,從PHP手冊
檢查腳本時間戳的更新頻率,以秒為單位。 0將導致OPcache檢查每個請求的更新。
所以正在發生的是你正在更新文件,但是你的指令說你在更新文件和opcache構建新操作碼之間的時間長達60秒。
validate_timestamps有答案。 因為您要手動重新驗證文件,所以可以執行此操作
禁用此偽指令時,必須通過opcache_reset(),opcache_invalidate()手動重置OPcache,或者重新啟動Web服務器以使文件系統的更改生效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.