说在前面
JIT
与Opcache
的区别- JIT 是在 Opcache 优化的基础上结合 Runtime 信息将字节码编译为机器码缓存起来
- 现有的 Opcache 优化不受任何影响,并且 PHP 的 JIT 是在 Opcache 中提供的
- JIT 不是对 Opcache 替代,而是增强,在启用 JIT 的情况下,如果 Zend 底层发现特定字节码已经编译为机器码,则可以绕过 Zend VM 直接让 CPU 执行机器码,从而提高代码性能。
JIT
主要针对CPU
密集型操作优化效果明显,而目前主流的PHP Web
应用都是IO
密集型操作,下面对命令行应用和Laravel
应用进行简单的基准测试。
Ubuntu
注:PHP 的 JIT 只能在 X86 架构下生效,所以使用 Intel CPU 的 PC、Mac、Linux 环境均可支持
VM
、WSL
、实机环境均可。
本次使用 WSL
下运行的Ubuntu。
编译安装 PHP 8
测试版
因为 PHP 8
还没有发布正式版本,只能下载源代码编译安装。
在此链接下载 PHP 8
测试最新版本,并解压进入。
开始编译安装流程。
// 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.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
源码目录下操作):
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 官方在源码中提供了一个基准测试文件,我们进入源码所在目录,通过如下命令测试不启动 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-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 应用中是如此。
小结
JIT 对 CPU 密集型操作优化效果很好,对 Web 应用性能是否有提升,取决于你的环境和配置的调优,因此 JIT 对 IO 密集型操作应用的性能优化效果有限,更适用于 CPU 密集型操作场景的性能优化,比如图像处理、机器学习等。
评论区