Opcache是什么?
Opcache是一種通過將解析的php腳本預編譯的字節碼(Operate Code)存放在共享內存中來避免每次加載和解析PHP腳本的開銷,解析器可以直接從共享內存讀取已經緩存的字節碼(Operate Code),從而大大提高PHP的執行效率。
什么是Operate Code?
當解釋器完成對腳本代碼的分析后,便將它們生成可以直接運行的中間代碼,也稱為操作碼(Operate Code,opcode)。Opcode cache的目的是避免重復編譯,減少CPU和內存開銷。如果動態內容的性能瓶頸不在于CPU和內存,而在于I/O操作,比如數據庫查詢帶來的磁盤I/O開銷,那么opcode cache的性能提升是非常有限的。但是既然opcode cache能帶來CPU和內存開銷的降低,這總歸是好事。現代操作碼緩存器(Optimizer+,APC2.0+,其他)使用共享內存進行存儲,并且可以直接從中執行文件,而不用在執行前“反序列化”代碼。這將帶來顯著的性能加速,通常特別是高流量和高并發量時降低了整體服務器的內存消耗,而且很少有缺點。
為什么要使用Opcode緩存?
這得從PHP代碼的生命周期說起,請求PHP腳本時,會經過五個步驟,如下圖所示:
Zend引擎必須從文件系統讀取文件、掃描其詞典和表達式、解析文件、創建要執行的計算機代碼(稱為Opcode),最后執行Opcode。每一次請求PHP腳本都會執行一遍以上步驟,如果PHP源代碼沒有變化,那么Opcode也不會變化,顯然沒有必要每次都重行生成Opcode,結合在Web中無所不在的緩存機制,我們可以把Opcode緩存下來,以后直接訪問緩存的Opcode豈不是更快,啟用Opcode緩存之后的流程圖如下所示:
因此使用了Operate Code緩存之后,PHP代碼會直接獲取opcode后直接執行,中間的三個步驟會省略掉因此會大幅提高PHP代碼執行效率。
PHP開啟opcache方法
1、打開php.ini文件
2、找到:[opcache],設置為:
[opcache] ; dll地址 zend_extension=php_opcache.dll ; 開關打開 opcache.enable=1 ; 開啟CLI opcache.enable_cli=1 ; 可用內存, 酌情而定, 單位為:Mb opcache.memory_consumption=528 ; Zend Optimizer + 暫存池中字符串的占內存總量.(單位:MB) opcache.interned_strings_buffer=8 ; 對多緩存文件限制, 命中率不到 100% 的話, 可以試著提高這個值 opcache.max_accelerated_files=10000 ; Opcache 會在一定時間內去檢查文件的修改時間, 這里設置檢查的時間周期, 默認為 2, 定位為秒 opcache.revalidate_freq=1 ; 打開快速關閉, 打開這個在PHP Request Shutdown的時候回收內存的速度會提高 opcache.fast_shutdown=1
3. 添加opcache.so
在php.ini最后一行添加opcache.so 主要作用是用來引用opcache
[root@abcDocker ~]# tail /etc/php.ini
zend_extension="opcache.so"
4. 重啟Nginx和php
設置例外
也許服務器上某些內容,比如正在進行調試的網站等,我們不希望對其進行 OPcache。那就可以通過黑名單來將需要例外的文件排除掉。在 OPcache 的配置文件中有一行配置,如下
opcache.blacklist_filename=/etc/php.d/opcache*.blacklist
該配置指定用于存儲文件名黑名單的那個文件。很顯然這里使用通配符 * 來指定了一系列文件而不僅僅是特定某個文件。可以一直啟用這一行。等到需要排除某些文件的時候,就編輯對應的黑名單文件。例如,針對 /srv/www/sites/devSite 文件夾下的所有文件,編輯(或者新建)文件
vim /etc/php.d/opcache-devSite.blacklist
內容為
/srv/www/sites/devSite/*
嗯,只有這么一行內容。通配符 * 表示所有 devSite 文件夾下的文件,完了之后重新啟動 php-fpm 服務就可以了。
systemctl restart php-fpm
體會與總結
PHP 上有不少 opcode cache 組件,如 APC、eAccelerator、XCache 等。(參見 Wikipedia 上的 PHP accelerators 列表。)看 PHP wiki 上的意思,這個新引入的 Zend Opcache 的性能應該是最好的。不管用哪個組件,總歸是用一個才好。
對于小型的服務器,似乎這幾個組件的性能差異并不太明顯。我的想法是,既然用了,那就用個最好的吧。但是如果你正在使用別的 opcode cache,比如上面提到的這幾個中的一個,從性能提升上講,倒是沒必要立刻就換。