php opcache 坑,PHP7 opcache缓存清理问题
PHP7 opcache緩存清理問題
背景
OPcache通過opcode的緩存和優(yōu)化,提供更快的PHP執(zhí)行過程。
業(yè)務(wù)在php7環(huán)境運(yùn)營(yíng)時(shí),為了提升請(qǐng)求的性能,在PHP7環(huán)境中配置OPcache擴(kuò)展。
業(yè)務(wù)在更新代碼后,訪問業(yè)務(wù)系統(tǒng)時(shí)提示無法找到對(duì)應(yīng)的文件或請(qǐng)求的內(nèi)容還是更新前的舊內(nèi)容,
webserver重啟以后,請(qǐng)求訪問到的文件就都是最新的了,問題就貌似解決了。
問題分析
根據(jù)現(xiàn)象分析,代碼更新后請(qǐng)求找不到新增的文件,尤其是還在請(qǐng)求已有文件更新前的內(nèi)容,那么可能跟緩存有關(guān)系,考慮到跟業(yè)務(wù)代碼邏輯無關(guān),關(guān)閉opcache的配置問題就不再出現(xiàn),基本上可以定位到問題出在opcache的配置上。
cat?/usr/local/php/etc/subconfig/opcache.inizend_extension=opcache.soopcache.enable=1opcache.revalidate_freq=0opcache.validate_timestamps=0opcache.max_accelerated_files=7963opcache.memory_consumption=192opcache.interned_strings_buffer=16opcache.fast_shutdown=1opcache.enable_cli=1
opcache.enable?啟用操作碼緩存,默認(rèn)為“1”
如果禁用此選項(xiàng),則不會(huì)優(yōu)化和緩存代碼。 在運(yùn)行期使用 ini_set() 函數(shù)只能禁用 opcache.enable 設(shè)置,不可以啟用此設(shè)置。 如果在腳本中嘗試啟用此設(shè)置項(xiàng)會(huì)產(chǎn)生警告。
opcache.enable_cli??僅針對(duì) CLI 版本的 PHP 啟用操作碼緩存。
通常被用來測(cè)試和調(diào)試。
opcache.revalidate_freq=0 ?檢查腳本時(shí)間戳是否有更新的周期,以秒為單位。
設(shè)置為 0 會(huì)導(dǎo)致針對(duì)每個(gè)請(qǐng)求, OPcache 都會(huì)檢查腳本更新。
opcache.validate_timestamps=0 ?如果啟用,那么 OPcache 會(huì)每隔 opcache.revalidate_freq 設(shè)定的秒數(shù) 檢查腳本是否更新。
如果禁用此選項(xiàng),你必須使用 opcache_reset() 或者 opcache_invalidate() 函數(shù)來手動(dòng)重置 OPcache,也可以 通過重啟 Web 服務(wù)器來使文件系統(tǒng)更改生效。
最初的配置是:
opcache.revalidate_freq=60,opcache.validate_timestamps=1
即每60秒檢測(cè)一次更新字節(jié)碼緩存,業(yè)務(wù)代碼更新后可能需要60秒以后才能訪問到最新的內(nèi)容,也就出現(xiàn)了最初訪問不到新增的內(nèi)容。
代碼更新方式
php代碼的更新方式有兩種,一種是覆蓋webserver配置的目錄下的文件來更新,一種是每次都部署一個(gè)全量包目錄,然后軟鏈接到webserver指定的目錄。
第一種覆蓋更新的方式,如果使用在過期時(shí)間后自動(dòng)清理opcache緩存內(nèi)容的話,更新操作如果有延遲,就會(huì)出現(xiàn)新舊代碼文件混合在一起的情況。
第二種全量包目錄發(fā)布后,軟鏈接到webserver指定路徑的方式,雖然不會(huì)存在新舊文件混合的問題,但是在未自動(dòng)清理時(shí),即便webserver已經(jīng)鏈接到webserver對(duì)應(yīng)目錄,業(yè)務(wù)訪問的還是舊文件。
代碼緩存的問題
目前使用rsync同步目錄文件的方式是我們更新代碼的主要方式,最初使用每60s定時(shí)清理opcache的緩存文件,在60s內(nèi)更新的文件不會(huì)生效,就導(dǎo)致了業(yè)務(wù)反饋代碼更新后訪問不到的問題。
使用定時(shí)更新代碼緩存的問題,還有更新文件較多時(shí),代碼文件發(fā)布的過程中緩存發(fā)生更新,將會(huì)有60s新舊文件的緩存混合存在的問題。
根據(jù)相關(guān)研究人員推薦,如果采用覆蓋更新代碼文件時(shí),更新操作完畢后,手動(dòng)清理緩存比較合適。opcache.validate_timestamps=0
即,將oopcache.validate_timestamps設(shè)置為0。
配置了opcache.validate_timestamps值為0,必須手動(dòng)清空Zend OPcache緩存的字節(jié)碼,才能訪問到最新的文件內(nèi)容。適合在生產(chǎn)環(huán)境中設(shè)置為0,但在開發(fā)環(huán)境會(huì)帶來不便,可以在開發(fā)環(huán)境中這樣配置啟用自動(dòng)驗(yàn)證緩存功能:
opcache.validate_timestamps=1
opcache.revalidate_freq=0
手動(dòng)清理緩存
除了重啟php-fpm的進(jìn)程可以清理opcache緩存外,
手動(dòng)清理緩存涉及到的opcache函數(shù)主要為:opcache_reset()和opcache_invalidate() 。123boolean?opcache_reset?(?void?)該函數(shù)將重置整個(gè)字節(jié)碼緩存。在調(diào)用?opcache_reset()?之后,所有的腳本將會(huì)重新載入并且在下次被點(diǎn)擊的時(shí)候重新解析。
需要注意的是,當(dāng)PHP以PHP-FPM的方式運(yùn)行的時(shí)候,opcache的緩存是無法通過php命令進(jìn)行清除的,只能通過http或cgi到php-fpm進(jìn)程的方式來清除緩存。In?some?(most?)?systems,PHP's?CLI?has?a?separate?opcode?cache?to?the?one?used?by?the?web?server?,or?PHP-FPM?process,which?means?running?opcache_reset()?in?the?CLI,won't?reset?the?webserver/fpm?opcode?cache,?and?vice-versa.
曲線救國,使用命令行清理php-fpm的opcache緩存:#!/bin/bashcgi-fcgi?-v??>?/dev/null?2>&1||?yum?--enablerepo=epel?install?fcgi?-y??>?/dev/null?2>&1echo?'<?php ?opcache_reset();?echo?"ok\n";'?>?/tmp/php-fpm-opcache-reset.php;SCRIPT_FILENAME=/tmp/php-fpm-opcache-reset.php?\REQUEST_METHOD=GET?\cgi-fcgi?-bind?-connect?127.0.0.1:9000;rm?-f?/tmp/php-fpm-opcache-reset.php;
opcache_invalidate ?廢除指定腳本緩存boolean?opcache_invalidate?(?string?$script?[,?boolean?$force?=?FALSE?]?)該函數(shù)的作用是使得指定腳本的字節(jié)碼緩存失效。?如果?force?沒有設(shè)置或者傳入的是?FALSE,那么只有當(dāng)腳本的修改時(shí)間?比對(duì)應(yīng)字節(jié)碼的時(shí)間更新,腳本的緩存才會(huì)失效。參數(shù)?script緩存需要被作廢對(duì)應(yīng)的腳本路徑force如果該參數(shù)設(shè)置為TRUE,那么不管是否必要,該腳本的緩存都將被廢除。
opcache_invalidate可以針對(duì)單個(gè)或幾個(gè)腳本進(jìn)行來清理緩存。
總結(jié)
如果代碼發(fā)布是全量發(fā)布,切換軟鏈接的方式,可以設(shè)置opcache.validate_timestamps=1和opcache.validate_timestamps=1來定時(shí)自動(dòng)更新緩存。
如果代碼發(fā)布是覆蓋更新舊目錄,則可以重啟php-fpm及在腳本中或代碼文件中使用opcache_reset函數(shù)來清理所有緩存。
如果可以獲取到更新的代碼文件列表,則可以使用opcache_invalidate函數(shù)來清理代碼,同時(shí)也可以避免影響到其他業(yè)務(wù)的緩存。
總結(jié)
以上是生活随笔為你收集整理的php opcache 坑,PHP7 opcache缓存清理问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java修改文件的大小限制_Struts
- 下一篇: php微信小程序物流进度推送,微信小程序