PHP專案中,尤其是在高並發大流量的場景中,如何提升PHP的回應時間,是一項十分重要的工作。
而Opcache又是優化PHP效能不可缺少的元件,尤其是應用了PHP框架的專案中,作用更是明顯。
在理解OPCache 功能之前,我們必須先理解PHP-FPM Nginx 的工作機制,以及PHP腳本解釋執行的機制。
1.1 PHP-FPM Nginx 的工作機制
請求從Web瀏覽器到Nginx,再到PHP處理完成,一共要經歷如下五個步驟:
第一步:啟動服務
第二步:Request => Nginx
第三步:Nginx => PHP-FPM
PHP-FPM master 程序接收到請求
PHP-FPM Worker 程序傳回處理結果,並關閉連接,等待下一個請求
1.2 PHP腳本解釋執行的機制了解了PHP Nginx 整體的處理流程後,我們接下來來看PHP腳本具體執行流程,
首先我們來看一個實例:
<?php if (!empty($_POST)) { echo "Response Body POST: ", json_encode($_POST), "\n"; } if (!empty($_GET)) { echo "Response Body GET: ", json_encode($_GET), "\n"; }
我們來分析執行過程:
php初始化執行環節,#啟動Zend引擎,載入註冊的擴充模組
初始化後讀取腳本文件,Zend引擎對腳本文件進行詞法分析(lex),語法分析(bison),產生語法樹
Zend 引擎編譯語法樹,產生opcode#,
Zend 引擎執行opcode,傳回執行結果
在PHP cli模式下,每次執行PHP腳本,四個步驟都會依序執行一遍;
在PHP-FPM模式下,步驟1)在PHP-FPM啟動時執行一次,後續的請求中不再執行;步驟2)~4)每個請求都要執行一遍;
其實步驟2)、3)產生的語法樹和opcode,同一個PHP腳本每次執行的結果都是一樣的,
在PHP-FPM模式下,每次請求都要處理一遍,是對系統資源極大的浪費,那麼有沒有辦法優化呢?
當然有,如:
OPCache 是Zend官方出品的,開放自由的opcode 快取擴展,還具有程式碼最佳化功能,省去了每次載入和解析PHP 腳本的開銷。
PHP 5.5.0 及後續版本中已經綁定了 OPcache 擴充。
快取兩類內容:
OPCache快取的機制主要是:將編譯好的操作碼放入共享內存,提供給其他進程存取#。
這裡就牽涉到記憶體共享機制,另外所有記憶體資源操作都有鎖定的問題,我們一一解讀。
3.1 共享記憶體
UNIX/Linux 系統提供許多進程間記憶體共享的方式:
當Wasted記憶體大於設定值時,自動重新啟動OPCache機制,清空並重新產生快取。
3.2 互斥鎖定
#任何記憶體資源的操作,都牽涉到鎖的機制。 共享記憶體:一個單位時間內,只允許一個程序執行寫入操作,允許多個程序執行讀取操作;寫入操作同時,不阻止讀取操作,以至於很少有鎖死的情況。 這就引發另一個問題:新程式碼、大流量場景,行程排隊執行快取opcode操作;重複寫入,導致資源浪費。4.1 OPCode 快取
#Opcache 會快取OPCode以及如下內容:4.2 Interned String 快取
首先我們需要理解,什麼是Interned String? 在PHP5.4的時候, 引入了Interned String機制, 用於優化PHP對字串的儲存和處理。 尤其是處理大塊的字串,例如PHP doces時,Interned String 可以優化記憶體。 Interned String 快取的內容包括:變數名稱、類別名稱、方法名稱、字串、註解等。
在PHP-FPM模式中,Interned String 快取字符,僅限於Worker 進程內部。 而快取到OPCache中,那麼Worker進程之間可以使用 Interned String 快取的字串,節省記憶體。 我們要注意一個事情,在PHP開發中,一般會有大段的註釋,也會被快取到OPCache。
可以透過php.ini的配置,關閉註解的快取。 但是,像Zend Framework等框架中,會引用註釋,所以,是否關閉註釋的緩存,需要區別對待。
在高流量的場景下,重建快取是一件非常耗費資源的事兒。
OPCache 在建立快取時並不會阻止其他進程讀取。 這會導致大量進程反覆新建快取。所以,不要設定OPCache過期時間
每次發布新程式碼時,都會出現重複新建快取的情況。如何避免呢? 進行編譯快取
#6.1 記憶體配置
mmap
,shm
, posix
以及 win32
。
64M
4M
5
6.2 允許快取的檔案數以及大小
##opcache .max_accelerated_files=2000 中找到的第一個等於設定值的質數大於設定值的質數。設定值取值範圍最小值是
200,最大值在 PHP 5.5.6 之前是
100000,PHP 5.5.6 及之後是
1000000。預設值
2000
opcache.max_file_size=0
opcache.load_comments
如果停用,則即使文件中包含註釋,也不會載入這些註釋內容。本選項可以和
opcache.save_comments 一起使用,以實現按需載入註解內容。
opcache.fast_shutdown
# 推薦學習:《PHP影片教學》
opcache.file_cache
設定二級快取目錄並啟用二級快取。啟用二級快取可以在 SHM 記憶體滿了、伺服器重新啟動或重置 SHM 的時候提高效能。預設值為空字串 ""
,表示停用基於檔案的快取。 opcache.file_cache_only
boolean
啟用或停用在共享記憶體中的 opcode 快取。 opcache.file_cache_consistency_checks
boolean
當從檔案快取載入腳本的時候,是否對檔案的校驗和進行驗證。 opcache.file_cache_fallback
boolean
在Windows 平台上,當一個行程無法附加到共享記憶體的時候, 使用基於檔案的緩存,也即: opcache.file_cache_only=1
。需要顯示的啟用檔案快取。
以上是深入分析PHP Opcache工作原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!