使用OPCache提高PHP的性能

對於 PHP 這樣的解釋型語言來講,每次的運行都會將全部的代碼進行一次加載解析,這樣一方面的好處是代碼隨時均可以進行熱更新修改,由於咱們不須要編譯。可是這也會帶來一個問題,那就是沒法承載過大的訪問量。畢竟每次加載解析再釋放,都會增長 CPU 的負擔,一般一臺 8核16G 的服務器在二、3000併發左右 CPU 就能達到60%以上的使用率。並且若是你使用的是相似於 Laravel 這種大型的框架,效率將更加低下。這個時候,咱們一般會經過增長服務器數量來作負載均衡,從而達到減輕服務器壓力的效果。不過,這樣作的成本又會增長許多。那麼,有沒有什麼優化的方案呢?php

鳥哥在他的博客中針對 PHP7 的優化的一篇文章中,第一條建議就是開啓 OPcache 。固然,另一個方案就是使用 Swoole 。關於 Swoole 的內容咱們未來再說,今天,咱們先學習學習 OPcache 。html

什麼是 OPcache

OPcache 經過將 PHP 腳本預編譯的字節碼存儲到共享內存中來提高 PHP 的性能, 存儲預編譯字節碼的好處就是 省去了每次加載和解析 PHP 腳本的開銷。緩存

這是 PHP 文檔中關於 OPcache 的簡介,也就是說,OPcache 節約了每次加載和解析的步驟,將第一次解析編譯後的腳本字節碼緩存到系統的共享內存中。其實,這就相似於一個不徹底的編譯。服務器

相似於 Java 之類的語言,都是要打包編譯以後才能上線運行的,好比打包成一個 jar包 。C++ 或 C# 能夠打包成一個 .dll 或 .exe 。這些打包以後的文件就是編譯完成的文件,將它們運行起來後通常會一直保持運行狀態,也就是會成爲一個常駐進程,它們的代碼就進入內存中了。在程序運行的時候,不須要再進行解釋或編譯,天然速度就要快不少。而 OPcache 也是起到相似的做用。只不過它並非徹底的一套編譯流程,咱們仍是依賴的 PHP-FPM 來運行腳本,只不過在開啓 OPcache 後,PHP-FPM 會先從內存中查找是否已經有相關的已經緩存的字節碼在內存中了,若是有的話就直接取用,若是沒有的話,會再次進行解釋編譯後緩存下來。另外,OPcache 是針對文件的,也就是說,一個文件若是是新增長進來的,只有運行過它纔會緩存,若是沒有運行過,它並不在當前的共享內存中。併發

安裝 Opcache

OPcache 已是 PHP 的官方擴展並隨安裝包一塊兒發佈了,因此,咱們能夠在編譯安裝 PHP 時使用 --enable-opcache 來開啓擴展,它已是默認擴展。也能夠在未安裝 OPcache 的系統中使用安裝包中的文件來進行安裝。mvc

cd php-7.4.4/ext/opcache/
phpize
./configure
make && make install

須要注意的是, OPcache 和 Xdebug 在生產環境中儘可能不要一塊兒使用。自己 Xdebug 就是不推薦在生產環境中使用的,若是必定須要同時使用的話,須要先加載 OPcache ,而後再加載 Xdebug 。負載均衡

擴展安裝後,在 php.ini 文件中打開擴展。須要注意的是,OPcache 擴展是 Zend 擴展包,因此咱們須要打開的是 Zend 擴展。框架

zend_extension=opcache.so

另外,還須要啓用它。php-fpm

opcache.enable=1

當開啓了 OPcache 以後,咱們再更新代碼將會發現剛剛更新的代碼不是咱們最新的代碼。這是由於代碼已經被緩存了,就像 Java 同樣,咱們須要重啓服務才行。那麼 PHP 這邊重啓的是什麼呢?固然就是重啓下咱們的 PHP-FPM 就能夠了,直接使用 kill -USR2 命令去重啓主進程就好了。這裏也給出一個快速重啓的命令。性能

ps -ef | grep "php-fpm: master" | grep -v grep | cut -c 9-15 | xargs kill -USR2
感謝知乎大佬的指正,重啓 PHP-FPM 不是最佳方案,應該使用 opcache_reset() 手動重啓,或者經過 php.ini 文件的配置 opcache.validate_timestamps + opcache.revalidate_freq 自動間隔編譯,或者經過 opcache_compile_file() 來直接從新編譯修改過的文件

ab 測試效果

咱們進行測試的內容是測試環境的一臺2核4G的服務器,使用的 PHP 版本是 PHP7.4 ,正常的 Nginx 及 PHP 配置, ulimit 也都開到了最大。代碼只是簡單的輸出了一行文字,不過咱們使用的是一個簡單的 mvc 框架 ,也就是說這段代碼運行起來至少也會加載幾個文件,而不是簡簡單單的一個文件。

首先咱們來看未開啓 OPcache 的狀況。

/img/bVcRAsw

接下來是開啓了 OPcache 的狀況。

/img/bVcRAsx

很明顯,性能有了很大的提升。不只速度快了不少,吞吐率也是直接上升了幾倍。固然,這只是很是簡單的一個測試,不過整體看來,確實對單機的性能提高有很大的幫助。最最主要的是,一樣的併發狀況下,CPU 資源也比未開啓的狀態下低了70%。

配置參考

在 PHP 的官方文檔中,已經爲咱們給出了一套默認的 OPcache 在 php.ini 中的配置。通過測試,基本沒什麼問題,固然,如今尚未在生產環境中使用過,還須要進行更多的測試。不過文檔中指出,這套配置是能夠直接運用到線上的,不過須要注意的是某些使用了註解之類功能的高級框架可能須要注意某些參數。

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

具體的配置說明以及其餘的一些配置選項咱們能夠參考官方文檔進行詳細的瞭解。

總結

既然是咱們的 PHP 大神鳥哥推薦的,並且也是官方推薦的擴展,我以爲在正式生產環境中使用不會有太大問題。另外,官方也給出了一套能夠直接運用於線上生產環境的配置參數,也方便咱們直接在線上進行測試。目前在生產環境中,咱們只使用了一臺服務器來進行測試,而且給它多分配了一些負載過來,從目前的狀況來看,這一臺機器的運行效率比其餘幾臺的高不少。由於它一方面處理了更多的請求,另外一方面它的 CPU 資源佔用率尚未其餘幾臺機器高。同時,OPcache 也不須要咱們去了解更多的進程協程之類的知識,不像 Swoole 同樣的會帶來更高的學習成本。因此綜上所述,在測試完備的狀況下,OPcache 絕對是咱們最優先考慮的單機優化方案。

參考文檔:
https://www.laruence.com/2015/12/04/3086.html
https://www.php.net/manual/zh/book.opcache.php

===========

各自媒體平臺都可搜索【硬核項目經理】

相關文章
相關標籤/搜索