PHP 8新特性之JIT對PHP應用性能的影響 最終運行結果如下:

前言

八重櫻:PHP 8 新特性​zhuanlan.zhihu.com

八重櫻:理解 PHP 8 的 JIT​zhuanlan.zhihu.com

即將發佈的 PHP 8 最受大家關注的新特性就是引入了對 JIT 的支持,我已經簡單介紹了 JIT 是什麼以及與 Opcache 的區別,這裏簡單總結下:

  • JIT 是在 Opcache 優化的基礎上結合 Runtime 信息將字節碼編譯爲機器碼緩存起來
  • 現有的 Opcache 優化不受任何影響,並且 PHP 的 JIT 是在 Opcache 中提供的
  • JIT 不是對 Opcache 替代,而是增強,在啓用 JIT 的情況下,如果 Zend 底層發現特定字節碼已經編譯爲機器碼,則可以繞過 Zend VM 直接讓 CPU 執行機器碼,從而提高代碼性能。

看起來很高大上,不過 JIT 主要針對 CPU 密集型操作優化效果明顯,而目前主流的 PHP Web 應用都是 IO 密集型操作,那麼 PHP 8 引入的 JIT 對這些 Web 應用的性能有沒有提升呢?爲此,特地編譯安裝了 PHP 8 Alpha 版本,並分別對命令行應用(CPU 密集型操作)和 Laravel 應用(IO 密集型操作)進行了簡單的基準測試來探個究竟。

歡迎加入我的官方羣

準備一個 Ubuntu 虛擬機

注:PHP 的 JIT 只能在 X86 架構下生效,所以使用 Intel CPU 的 PC、Mac、Linux 環境均可支持。

由於目前 PHP 8 還沒有正式發佈,只能下載源代碼編譯安裝,所以需要準備一個 Linux 環境作爲測試環境。不少同學跟我反映沒怎麼在 Windows 上演示過操作流程,所以今天我特地選擇在 Windows 10 專業版中通過 WSL 來安裝 Ubuntu 18.04 作爲演示環境,這個比通過 Virtual Box 或者 VMWare 安裝虛擬機簡單多了,不得不說,從 Windows 10 開始,對開發者越來越友好了,雖然比起 Mac 還是有些距離,畢竟 Mac 是原生的類 Unix 系統。

言歸正傳,安裝 WSL 版 Ubuntu 虛擬機 Windows 官方提供了相應的文檔:Windows Subsystem for Linux Installation Guide for Windows 10 照着做就好了,非常簡單,在 Windows 商店下載安裝後,就可以點擊啓動按鈕啓動這個 Ubuntu 虛擬機了:


打開後的界面是這樣的,看起來和一個終端窗口差不多:

這個虛擬機使用起來的體驗比傳統的虛擬機要簡單一些,比如直接可以調用 Windows 宿主機的程序,比如 VS Code,在虛擬機中通過 Nginx 管理的 Web 應用也可以直接從 Windows 宿主機的瀏覽器訪問,無需配置端口映射,所以用來作爲本地 Linux 測試開發環境很方便。

當然,如果你不想嚐鮮的話,使用傳統的虛擬機或者原生的 Ubuntu 系統都可以。

演示項目初始化
接下來,我們需要通過上面打開的終端窗口在這個 Ubuntu 虛擬機中安裝 Nginx,以及 PHP、Composer,通過以下幾個命令就可以搞定了:

sudo apt install nginx

sudo apt install php php-zip php-mbstring

sudo apt install composer
然後通過 Composer 在 Nginx 默認 Web 根目錄 /var/www 目錄下安裝用於演示的 Laravel Web 項目(下載速度慢可以配置 Composer 全局鏡像):

sudo composer create-project --prefer-dist laravel/laravel blog 6.* -vvv
初始化完成後,可以通過 php artisan serve 測試下這個項目訪問是否正常。這裏就不演示了。

編譯安裝 PHP 8 測試版
完成上述準備工作後,就可以開始 PHP 8 測試版本的編譯安裝了,首先,我們從 Github 下載 PHP 8 測試版本源碼(PHP 官網源碼包下載太慢):

解壓並進入源碼根目錄:

tar zxvf php-8.0.0alpha2.tar.gz
cd php-8.0.0alpha2
開始編譯安裝流程:

// 1、安裝相關依賴庫

sudo apt install -y pkg-config build-essential autoconf bison re2c libxml2-dev \

libsqlite3-dev libssl-dev libcurl4-openssl-dev libpng-dev libonig-dev libzip-dev

 

// 2、生成 configure 文件

./buildconf --force

 

// 3、配置構建流程

./configure --prefix=/usr/local/php8 \

--with-config-file-path=/usr/local/php8 \

--enable-mbstring  \

--enable-ftp  \

--enable-gd   \

--enable-mysqlnd \

--enable-pdo   \

--enable-sockets   \

--enable-fpm   \

--enable-xml  \

--enable-soap  \

--enable-pcntl   \

--enable-cli   \

--enable-json  \

--enable-tokenizer \

--enable-ctype \

--enable-bcmath  \

--with-openssl  \

--with-pear   \

--with-zlib  \

--with-iconv  \

--with-curl  \

--with-zip

 

// 4、構建

make

 

// 5、安裝

sudo make install

最後一步執行成功後,會有 PHP 8 安裝成功的提示文本,你也可以通過如下命令驗證安裝成功:



當前 PHP 8 被安裝到了 /usr/local/php8 這個目錄下。

初始化配置文件
編譯安裝的 PHP 8 需要自行拷貝和設置配置文件,我們首先將基礎配置文件 php.ini 從源代碼目錄拷貝到 PHP 的安裝目錄:

sudo cp php.ini-production /usr/local/php8/php.ini

由於 JIT 是在 Opcache 擴展中提供的,所以需要先啓動這個擴展,打開 /usr/local/php8/php.ini,取消對如下配置項的註釋(刪除前面的分號即可):

zend_extension=opcache.so

opcache.enable=1

opcache.enable_cli=1

然後來初始化 PHP-FPM 的配置文件。

先把 php8.0-fpm 二進制文件拷貝到 /etc/init.d 目錄下(還是在 php-8.0.0alpha2 源碼目錄下操作):

sudo cp sapi/fpm/init.d.php-fpm /etc/init.d/php8.0-fpm

sudo chmod +x /etc/init.d/php8.0-fpm

進入 /usr/local/php8/etc 目錄,初始化 PHP-FPM 配置文件:

cd /usr/local/php8/etc

sudo cp php-fpm.conf.default php-fpm.conf

通過 vim 編輯器打開 php-fpm.conf,修改如下配置項(同時取消前面的分號註釋):

pid = /run/php/php8.0-fpm.pid

然後進入當前目錄下的 php-fpm.d 子目錄:

cd php-fpm.d

sudo cp www.conf.default www.conf

打開 www.conf,修改如下配置項(同時取消前面的分號註釋):

user = www-data

group = www-data

 

listen = /run/php/php8.0-fpm.sock

 

listen.owner = www-data

listen.group = www-data

listen.mode = 0660

命令行應用基準測試
完成上述準備工作後,就可以正式開始測試工作了。

首先,我們來測試命令行應用,PHP 官方在源碼中提供了一個基準測試文件,我們進入源碼所在目錄 php-8.0.0alpha2,通過如下命令測試不啓動 JIT 情況下代碼運行情況:

/usr/local/php8/bin/php -d opcache.jit_buffer_size=0 Zend/bench.php

運行結果如下(運行時間,單位爲 s):



然後,再通過下面這條命令測試啓動 JIT 的情況下命令行代碼的運行情況:

/usr/local/php8/bin/php -d opcache.jit_buffer_size=64M -d opcache.jit=1205 Zend/bench.php

注:關於 opcache.jit_buffer_size 配置項比較好理解,而 opcache.jit 配置項對應配置值的每個數字代表不同含義,具體可以參考鳥哥的這篇博客:PHP 8 新特性之 JIT 簡介,裏面講得非常詳細,一般對於命令行應用,將該配置值配置爲 1205,對於 Web 應用,配置爲 1235 或者 1255。

最終運行結果如下:

可以看到,在 CPU 密集型操作的命令行應用中,啓用 JIT 與不啓用相比,耗時降低了接近 60%,性能提升了 2 倍。

Web 應用基準測試
接下來,我們以 Laravel 演示項目爲例,演示 PHP Web 應用中啓用 JIT 與不啓用性能有沒有提升。

啓動 PHP-FPM:

sudo /etc/init.d/php8.0-fpm start

在 Nginx 中配置一個新的虛擬主機(/etc/nginx/sites-available/blog):

server {

    listen 80;

    server_name blog.test;

    root /var/www/blog/public;

 

    index index.html index.htm index.php;

 

    charset utf-8;

 

    location / {

        try_files $uri $uri/ /index.php?$query_string;

    }

 

    location = /favicon.ico { access_log off; log_not_found off; }

    location = /robots.txt  { access_log off; log_not_found off; }

 

    error_page 404 /index.php;

 

    location ~ \.php$ {

        fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;

        fastcgi_index index.php;

        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

        include fastcgi_params;

    }

 

    location ~ /\.(?!well-known).* {

        deny all;

    }

}

然後進入 /etc/nginx/sites-enable 目錄,創建這個虛擬主機的軟連接:

sudo ln -s /etc/nginx/sites-available/blog blog

啓動 Nginx:

sudo service nginx start

在 Windows 系統的 C:\Windows\System32\drivers\etc\hosts 文件中添加虛擬域名與主機地址的映射:

127.0.0.1 blog.test

此時可以在 Windows 宿主機中通過瀏覽器訪問對應的 Laravel 項目,表示部署成功:



然後,我們還是在 Windows 中,通過 ab 命令對 blog.test 首頁進行壓力測試(此時尚未啓用 JIT):

ab -n 10 -c 10 http://blog.test/

注:-n 表示總請求數,-c 表示最大併發請求數。
測試結果如下,重點關注 RPS(每秒處理請求數):


最後,在 Ubuntu 虛擬機中,打開 PHP 8 的配置文件 /usr/local/php8/php.ini,在 Opcache 配置項下新增 JIT 配置:

opcache.jit=1235

opcache.jit_buffer_size=64M

配置完成後,重啓 PHP-FPM 服務,再次回到 Windows 宿主機,通過 ab 命令對 http://blog.test 頁面進行壓力測試:

ab -n 10 -c 10 -s 60 http://blog.test/

注:-s 表示超時時間。

運行結果如下:


可以看到在 IO 密集型操作的 Web 應用中,啓用 JIT 與不啓用相比,性能不但沒有提升,反而有 10% 左右的損耗,至少在 Laravel 應用中是如此。

小結
當然,這裏的測試僅限於的 Ubuntu 虛擬機環境(Windows WSL 版,配置是 8C8G),並且我也只是將 JIT 參數調整爲官方建議的參數,沒有做更多的對比測試,但是可以肯定的是 JIT 對 CPU 密集型操作優化效果很好,對 Web 應用性能是否有提升,取決於你的環境和配置的調優,因此 JIT 對 IO 密集型操作應用的性能優化效果有限,更適用於 CPU 密集型操作場景的性能優化,比如圖像處理、機器學習等。

很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了迷茫沒方向,不知道該從哪兒入手去提升自己。→→管理整理了一些資料,有 騰訊 等一線大廠進階知識體系 可供參考(相關學習資料以及筆面試題)

覆蓋各個技術棧:分佈式架構、高可擴展、高性能、高併發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨歡迎加入我的官方羣點擊此處

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章