1
/
5

PHP7.4のpreloadでLaravel7を高速化!?

Photo by Studio Proper on Unsplash

弊社エンジニアブログからの転送です
詳しくは
https://www.aska-ltd.jp/jp/blogs
をご覧ください。

これまでシステム開発終盤の負荷試験で思うような性能が出ずに、「(;;´ )ε( `;;)・・・う~ん」と悩まされることが何度かありました。

しかしそういった場合でも、比較的ローコストで改善する方法がないかと考えていたところ、PHP7.4のpreloadと呼ばれる新機能でパフォーマンスが向上したという記事を目にしました。

「プリロード」、、、なんて素敵な響き、きっと速くなるに違いない!と思い、自分でも検証してみることにしました。

ちなみにpreloadとは、サーバ起動時に指定したスクリプトを読み込み、それをコンパイルしたものをメモリに載せて、全てのリクエストにおいてそのキャッシュを利用するという機能のことです。

やること
「preloadなし」と「preloadあり」でLaravelのベンチマークをとる。

環境
CentOS 7.7 Nginx 1.17.9 php-fpm 7.4.4 Laravel 7
VirtualBox+Dockerで環境を構築しました。

事前準備
abコマンド
abコマンドで性能測定するので次のようにhttpd-toolsが必要になります。

yum install -y httpd-tools

検証用スクリプト
固定のjson文字列を返却するだけのシンプルなAPIで検証することにしました。

app/Http/Controllers/TestController.php
<?php
namespace App\Http\Controllers;

class TestController extends Controller
{
public function hello()
{
return response()->json([
'message' => 'Hello World!',
]);
}
}
routes/web.php
<?php
・・・
Route::get('test/hello', 'TestController@hello');
preloadするためのスクリプト
PHP RFCにあるヘルパー関数をほぼそのまま流用します。 https://wiki.php.net/rfc/preload#proposal

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.56.101 (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx/1.17.9 Server Hostname: 192.168.56.101 Server Port: 80 Document Path: /test/hello Document Length: 26 bytes Concurrency Level: 100 Time taken for tests: 9.755 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 963000 bytes HTML transferred: 26000 bytes Requests per second: 102.51 [#/sec] (mean) Time per request: 975.520 [ms] (mean) Time per request: 9.755 [ms] (mean, across all concurrent requests) Transfer rate: 96.40 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.6 0 3 Processing: 28 905 191.9 930 1478 Waiting: 28 905 191.9 929 1478 Total: 31 905 191.4 930 1478 Percentage of the requests served within a certain time (ms) 50% 930 66% 961 75% 989 80% 1021 90% 1094 95% 1141 98% 1195 99% 1299 100% 1478 (longest request) 1秒あたり102.51リクエストを処理しています。 別途、1回のリクエストでLaravelがインクルードしているファイル数を調べたところ、410ファイルを読み込んでいました。 preloadあり $ ab -n 1000 -c 100 http://192.168.56.101/test/hello This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.56.101 (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx/1.17.9 Server Hostname: 192.168.56.101 Server Port: 80 Document Path: /test/hello Document Length: 26 bytes Concurrency Level: 100 Time taken for tests: 8.429 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 963000 bytes HTML transferred: 26000 bytes Requests per second: 118.63 [#/sec] (mean) Time per request: 842.933 [ms] (mean) Time per request: 8.429 [ms] (mean, across all concurrent requests) Transfer rate: 111.57 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.7 0 3 Processing: 25 805 211.2 784 1388 Waiting: 22 805 211.2 784 1388 Total: 25 805 210.9 784 1390 Percentage of the requests served within a certain time (ms) 50% 784 66% 803 75% 818 80% 829 90% 978 95% 1355 98% 1370 99% 1377 100% 1390 (longest request) 1秒あたり118.63リクエストを処理しています。 何度か実行しましたが、 「preloadあり」のほうが「preloadなし」より10%~15%ほど性能が良かったです。 インクルードしているファイル数も236に減っていました。 まとめ preloadによりLaravelのパフォーマンスは向上しました。 しかし、OPcacheを無効→有効にすると10倍ほどパフォーマンスが向上していたので、それと比較すると思ったほどのインパクトはないというのが正直なところです。 Laravelの機能をもっと多く利用したアプリだと効果が大きいのかもしれませんが、opcache_compile_file関数で落ちてしまう問題や、preloadで読み込んだはずの一部のスクリプトがなぜか実行時にも読み込まれていたりと、枯れた技術ではないという印象でした。 現時点だと、よほどパフォーマンスを重視したいという理由以外で、本番環境で使用することはなさそうです。 う~ん、、、まぁ近々正式リリースされるPHP8のJITは爆速らしいので、そちらも検証してみたいです。

株式会社あすかでは一緒に働く仲間を募集しています

今週のランキング

宗近 龍一郎さんにいいねを伝えよう
宗近 龍一郎さんや会社があなたに興味を持つかも