您好,登錄后才能下訂單哦!
這篇文章主要講解了“PHP的優(yōu)化加速組件Opcache怎么使用”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“PHP的優(yōu)化加速組件Opcache怎么使用”吧!
Opcache是一種通過(guò)將解析的PHP腳本預(yù)編譯的字節(jié)碼(Operate Code)存放在共享內(nèi)存中來(lái)避免每次加載和解析PHP腳本的開(kāi)銷(xiāo),解析器可以直接從共享內(nèi)存讀取已經(jīng)緩存的字節(jié)碼(Operate Code),從而大大提高PHP的執(zhí)行效率。
這得從PHP代碼的生命周期說(shuō)起,請(qǐng)求PHP腳本時(shí),會(huì)經(jīng)過(guò)五個(gè)步驟,如下圖所示:
Zend引擎必須從文件系統(tǒng)讀取文件、掃描其詞典和表達(dá)式、解析文件、創(chuàng)建要執(zhí)行的計(jì)算機(jī)代碼(稱(chēng)為Opcode),最后執(zhí)行Opcode。每一次請(qǐng)求PHP腳本都會(huì)執(zhí)行一遍以上步驟,如果PHP源代碼沒(méi)有變化,那么Opcode也不會(huì)變化,顯然沒(méi)有必要每次都重行生成Opcode,結(jié)合在Web中無(wú)所不在的緩存機(jī)制,我們可以把Opcode緩存下來(lái),以后直接訪(fǎng)問(wèn)緩存的Opcode豈不是更快,啟用Opcode緩存之后的流程圖如下所示:
Opcode是一種PHP腳本編譯后的中間語(yǔ)言,就像Java的ByteCode,或者.NET的MSL,舉個(gè)例子,比如你寫(xiě)下了如下的PHP代碼:
echo "Hello World"; $a = 1 + 1; echo $a; ?>
PHP執(zhí)行這段代碼會(huì)經(jīng)過(guò)如下4個(gè)步驟(確切的來(lái)說(shuō),應(yīng)該是PHP的語(yǔ)言引擎Zend)
1)Scanning(Lexing) ,將PHP代碼轉(zhuǎn)換為語(yǔ)言片段(Tokens)。 2)Parsing, 將Tokens轉(zhuǎn)換成簡(jiǎn)單而有意義的表達(dá)式。 3)Compilation, 將表達(dá)式編譯成Opocdes。 4)Execution, 順次執(zhí)行Opcodes,每次一條,從而實(shí)現(xiàn)PHP腳本的功能。
Optimizer+(Optimizer+于2013年3月中旬改名為Opcache),OPcache通過(guò)將PHP腳本預(yù)編譯的字節(jié)碼存儲(chǔ)到共享內(nèi)存中來(lái)提升PHP的性能,存儲(chǔ)預(yù)編譯字節(jié)碼的好處就是省去了每次加載和解析PHP腳本的開(kāi)銷(xiāo)。
PHP 5.5.0 及后續(xù)版本中已經(jīng)綁定了 OPcache 擴(kuò)展。 對(duì)于 PHP 5.2,5.3 和 5.4 版本可以使用 » PECL擴(kuò)展中的OPcache庫(kù)。
PHP 5.5.0及后續(xù)版本
OPcache只能編譯為共享擴(kuò)展。如果你使用–disable-all參數(shù)禁用了默認(rèn)擴(kuò)展的構(gòu)建,那么必須使用–enable-opcache選項(xiàng)來(lái)開(kāi)啟OPcache。編譯之后,就可以使用 zend_extension 指令來(lái)將 OPcache 擴(kuò)展加載到 PHP 中。
推薦的php.ini設(shè)置
使用下列推薦設(shè)置來(lái)獲得較好的性能:
opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60 opcache.fast_shutdown=1 opcache.enable_cli=1 opcache.save_comments=0
你也可以禁用 opcache.save_comments 并且啟用 opcache.enable_file_override。 需要提醒的是,在生產(chǎn)環(huán)境中使用上述配置之前,必須經(jīng)過(guò)嚴(yán)格測(cè)試。 因?yàn)樯鲜雠渲么嬖谝粋€(gè)已知問(wèn)題,它會(huì)引發(fā)一些框架和應(yīng)用的異常, 尤其是在存在文檔使用了備注注解的時(shí)候。
以下是opcache的配置說(shuō)明,其中給有值得都是默認(rèn)配置:
; opcache的開(kāi)關(guān),關(guān)閉時(shí)代碼不再優(yōu)化. opcache.enable=1 ; Determines if Zend OPCache is enabled for the CLI version of PHP opcache.enable_cli=1 ; OPcache的共享內(nèi)存大小,以兆字節(jié)為單位。總共能夠存儲(chǔ)多少預(yù)編譯的PHP代碼(單位:MB) ; 推薦128 opcache.memory_consumption=64 ; 用來(lái)存儲(chǔ)臨時(shí)字符串的內(nèi)存大小,以兆字節(jié)為單位. ; 推薦8 opcache.interned_strings_buffer=4 ; 最大緩存的文件數(shù)目200到100000之間. ; 推薦4000 opcache.max_accelerated_files=2000 ; 內(nèi)存"浪費(fèi)"達(dá)到此值對(duì)應(yīng)的百分比,就會(huì)發(fā)起一個(gè)重啟調(diào)度. opcache.max_wasted_percentage=5 ; 開(kāi)啟這條指令, Zend Optimizer + 會(huì)自動(dòng)將當(dāng)前工作目錄的名字追加到腳本鍵上,以此消除同名文件間的鍵值命名沖突.關(guān)閉這條指令會(huì)提升性能,但是會(huì)對(duì)已存在的應(yīng)用造成破壞. opcache.use_cwd=0 ; 開(kāi)啟文件時(shí)間戳驗(yàn)證 opcache.validate_timestamps=1 ; 檢查腳本時(shí)間戳是否有更新的周期,以秒為單位。設(shè)置為0會(huì)導(dǎo)致針對(duì)每個(gè)請(qǐng)求,OPcache都會(huì)檢查腳本更新. ; 推薦60 opcache.revalidate_freq=2 ; 允許或禁止在include_path中進(jìn)行文件搜索的優(yōu)化. opcache.revalidate_path=0 ; 如果禁用,腳本文件中的注釋內(nèi)容將不會(huì)被包含到操作碼緩存文件,這樣可以有效減小優(yōu)化后的文件體積,禁用此配置指令可能會(huì)導(dǎo)致一些依賴(lài)注釋或注解的應(yīng)用或框架無(wú)法正常工作,比如:Doctrine,Zend Framework2等. ; 推薦0 opcache.save_comments=1 ; 如果禁用,則即使文件中包含注釋?zhuān)膊粫?huì)加載這些注釋內(nèi)容。本選項(xiàng)可以和opcache.save_comments一起使用,以實(shí)現(xiàn)按需加載注釋內(nèi)容. opcache.load_comments=1 ; 打開(kāi)快速關(guān)閉,打開(kāi)這個(gè)在PHP Request Shutdown的時(shí)候會(huì)收內(nèi)存的速度會(huì)提高. ; 推薦1 opcache.fast_shutdown=1 ; 允許覆蓋文件存在(file_exists等)的優(yōu)化特性. opcache.enable_file_override=0 ; 定義啟動(dòng)多少個(gè)優(yōu)化過(guò)程. opcache.optimization_level=0xffffffff ; 啟用此Hack可以暫時(shí)性的解決"can’t redeclare class"錯(cuò)誤. opcache.inherited_hack=1 ; 啟用此Hack可以暫時(shí)性的解決"can’t redeclare class"錯(cuò)誤. ;opcache.dups_fix=0 ; 通過(guò)文件大小屏除大文件的緩存,默認(rèn)情況下所有的文件都會(huì)被緩存. ;opcache.max_file_size=0 ; 每N次請(qǐng)求檢查一次緩存校驗(yàn).默認(rèn)值0表示檢查被禁用了,由于計(jì)算校驗(yàn)值有損性能,這個(gè)指令應(yīng)當(dāng)緊緊在開(kāi)發(fā)調(diào)試的時(shí)候開(kāi)啟. ;opcache.consistency_checks=0 ; 從緩存不被訪(fǎng)問(wèn)后,等待多久后(單位為秒)調(diào)度重啟. ;opcache.force_restart_timeout=180 ; 日志記錄level,默認(rèn)只有fatal error和error. ;opcache.error_log= ; 將錯(cuò)誤信息寫(xiě)入到服務(wù)器(Apache等)日志 ;opcache.log_verbosity_level=1 ; 內(nèi)存共享的首選后臺(tái).留空則是讓系統(tǒng)選擇. ;opcache.preferred_memory_model= ; 運(yùn)行php腳本時(shí)保護(hù)共享內(nèi)存防止意外的寫(xiě)入,只對(duì)debug時(shí)有用. ;opcache.protect_memory=0
最后說(shuō)一下使用opcache加速php時(shí)應(yīng)該注意的坑:
opcache依靠的是PHP文件的modify time作為文件被修改的檢測(cè)條件,基于這個(gè)會(huì)引發(fā)兩個(gè)問(wèn)題。
第一個(gè)問(wèn)題是做版本回滾時(shí),由于版本回滾后的文件修改時(shí)間比現(xiàn)有opcache緩存的文件時(shí)間要往前一些,所以可能會(huì)導(dǎo)致opcache不會(huì)清除緩存,需要手動(dòng)reload。
第二個(gè)問(wèn)題是做版本發(fā)布時(shí),一般都是sync方式,可能會(huì)出現(xiàn)文件發(fā)布一半時(shí)被opcache緩存,用戶(hù)訪(fǎng)問(wèn)會(huì)報(bào)程序錯(cuò)誤,這個(gè)主要是因?yàn)槲募?nèi)容緩存了一半,但是文件的時(shí)間戳不會(huì)在改變,所以就算opcache檢測(cè)時(shí)也不會(huì)去讀取新的文件了,需要手動(dòng)reload。
針對(duì)這兩個(gè)問(wèn)題,不光reload可以解決,同樣調(diào)用opcache的接口也可以清除opcache緩存。
你可以使用opcache_reset()或者或者opcache_invalidate()函數(shù)來(lái)手動(dòng)重置OPcache。
opcache_reset():該函數(shù)將重置整個(gè)字節(jié)碼緩存,在調(diào)用opcache_reset()之后,所有的腳本將會(huì)重新載入并且在下次被點(diǎn)擊的時(shí)候重新解析。
opcache_invalidate():該函數(shù)的作用是使得指定腳本的字節(jié)碼緩存失效。 如果force沒(méi)有設(shè)置或者傳入的是FALSE,那么只有當(dāng)腳本的修改時(shí)間 比對(duì)應(yīng)字節(jié)碼的時(shí)間更新,腳本的緩存才會(huì)失效。
但是不推薦使用,個(gè)人在生產(chǎn)環(huán)境中進(jìn)行代碼發(fā)布后調(diào)用opcache_reset()清空緩存(測(cè)試確實(shí)可以清空緩存),出現(xiàn)過(guò)奇葩問(wèn)題(訪(fǎng)問(wèn)量大的應(yīng)用),后來(lái)就果斷放棄了,使用了reload的方式。
感謝各位的閱讀,以上就是“PHP的優(yōu)化加速組件Opcache怎么使用”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)PHP的優(yōu)化加速組件Opcache怎么使用這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。