2020年11月26日に、PHP8がリリースされました。
PHP8では実行時(JIT)コンパイラーが導入されているため、リクエストがくるとソースコードがネイティブコードに変換されます。
もう一度同じ処理がリクエストされると、そのネイティブコードをそのまま実行することで処理が高速化され、1.5~2倍の処理速度向上が見込めるとのことです。
今回は、コンテナでCentOS7をベースにPHP8を入れて使ってみたいと思います。
※普段は、alpineを利用していますが、時間短縮のためパッケージとしてPHP8が用意されていたのがCentOSを利用してます。
php-fpmコンテナ(CentOS)
phpとphp-fpmを稼働させるコンテナのため、以下2つのファイルを作成します。
Dockerfile
FROM centos:7
RUN yum -y update && yum clean all
RUN yum -y install epel-release
RUN yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
RUN yum -y --enablerepo=remi,remi-php80 install php php-mbstring php-pdo php-mysqlnd php-gd php-xml php-fpm pphp-crypt php-pear php-common php-pecl-zip php-process php-cli php-devel
RUN mkdir /run/php-fpm
RUN useradd -u 105 -U nginx && \
groupmod -g 105 nginx
COPY ./php/www.conf /etc/php-fpm.d/www.conf
EXPOSE 9000
CMD ["php-fpm", "-F"]
phpとphp-fpmが稼働する、最低限の内容としています。
以下、各行の内容となります。
3行目
RUN yum -y update && yum clean all
OSのシステムアップデートなどを行います。
4~5行目
RUN yum -y install epel-release
RUN yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
CentOSで利用可能なリポジトリ、epelとremiを追加します。
7行目
RUN yum -y --enablerepo=remi,remi-php80 install php php-mbstring php-pdo php-mysqlnd php-gd php-xml php-fpm pphp-crypt php-pear php-common php-pecl-zip php-process php-cli php-devel
追加したリポジトリより、PHP8をインストールします。
幾つか、不要かもしれない内容が含まれているかも・・・しれません。
ちなみにインストール可能な内容は、以下のURLから確認が可能です。
https://rpms.remirepo.net/enterprise/7/php80/x86_64/repoview/
9~10行目
RUN mkdir /run/php-fpm
RUN useradd -u 105 -U nginx && \
groupmod -g 105 nginx
php-fpmが稼働する際に必要なディレクトリと、php-fpmの実行ユーザー/グループを作成(変更)しています。
12行目
COPY ./php/www.conf /etc/php-fpm.d/www.conf
php-fpmの設定ファイルをコピーします。
※ここは、docker-compose側で指定の方が楽かもしれない。
14行目
EXPOSE 9000
コンテナで利用するポートは、php-fpmで利用する9000ですので、こちらを指定しておきます。
16行目
CMD ["php-fpm", "-F"]
php-fpmをフォアグラウンドで実行させます。
www.conf
[www]
listen = 9000
listen.owner = nginx
listen.group = nginx
listen.mode = 0666
user = nginx
group = nginx
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
変更している箇所は、listenやuser、groupのあたりとなります。
IPは指定せずポートだけで待ち受けるため、listenについては9000とポートだけを指定する様にしています。
また、userとgroupについても、コンテナ作成時に作られるnginxを指定しています。
Nginxコンテナ
Nginxのコンテナについては、ほぼイメージのままで利用します。
最終的に、docker-composeで2つのコンテナをアップするので、その際に利用する、default.conf だけ先に作成しておきます。
default.conf
server {
listen 80;
server_name _;
root /var/www/html;
index index.php index.html;
access_log /var/log/nginx/access.log ltsv;
error_log /var/log/nginx/error.log;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(\.+)$;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
docker-composeファイルを用意する
Nginxとphp-fpm、2つのコンテナをアップするためのdocker-compose.ymlを作成します。
version: "2"
services:
nginx:
image: nginx:1.19-alpine
container_name: nginx
restart: always
ports:
- 80:80
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./data:/var/www
links:
- php-fpm
depends_on:
- php-fpm
php-fpm:
build: ./php-fpm
container_name: php-fpm
restart: always
Nginxをアップする際に、先ほど作成したdefault.confを上書きする様に、volumesに指定をしておきます。
コンテナを起動する
起動する前に、buildを行います。
docker-compose build
buildが完了したら、以下のコマンドでコンテナを起動します。
docker-compose up -d
コンテナが起動したら、動いているかを見てみます。
docker-compose ps
コマンドを実行すると、以下のように表示されるはずです。
nginx /docker-entrypoint.sh ngin … Up 0.0.0.0:80->80/tcp php-fpm php-fpm -F Up 9000/tcp
起動したコンテナで、PHP8が動いているか確認してみました。
ちゃんと動いている様です・・・。
PHP8のパフォーマンスを確認する
コンテナを立ち上げるところまでは無事終わったので、どのくらいパフォーマンスに違いがあるのかを確認したいと思います。
比較に利用させてもらったのは、以下のページのものとなります。
PHPコードの処理速度を比較するためのベンチマーク計測用関数を自作する
https://wemo.tech/1486
記載されていたコードを、data/html/以下にtest.phpとして設置しました。
また、比較のため開発環境として利用している、Nginx+PHP7.3でも同様の内容を実行してみました。
PHP7 環境
- AlpineLinux + Nginx(1.19)
- AlpineLinux + php-fpm(php7.3)
PHP8 環境
- AlpineLinux + Nginx(1.19)
- CentOS + php-fpm(php8.0)
実行結果
PHP7
1回目:0.0003364086秒
2回目:0.0003226990秒
3回目:0.0003410038秒
4回目:0.0003613277秒
5回目:0.0003455382秒
PHP8
1回目:0.0002960610秒
2回目:0.0002974842秒
3回目:0.0002891736秒
4回目:0.0002942722秒
5回目:0.0002822718秒
総括
まさか、ただのループ処理だけでこんなに違いがでるなんて・・・想像もしてなかったため、複雑な処理やDB接続などもっと違う処理やWordPress、各種フレームワークでのベンチも、時間を見つけて取りたいと思います。
また、AlpineLinuxでもPHP8を利用できるよう、環境を作っていく予定です。