インフラエンジニアの nobuh です。 高性能な Web サービスを簡単に構築出来ることで評判の良い Microsoft の .NET ですが、 .NET Core でオープンソース化されたことで、最近身近に感じることが多くなってきました。
そんななか、PHP のソースを事前コンパイルして .NET のランタイムで実行し、C# と PHP の相互運用を可能にするという、赤じゃなくてオレンジ色がテーマカラーのオープンソースプロジェクト PeachPie というのを見つけました。
性能では定評のある .NET Core / .NET で PHP が動くというだけでワクワクしますね! ということで早速使ってみました。
.NET 5 のインストール
今回のテストで使っているのは Ubuntu 20.04 LTS の PC です。
Microsoft の .NET 5 の Download ページ の Ubuntu 20.04 向けパッケージマネージャーでのインストール方法 にしたがって dotnet-sdk-5.0 をインストールしました
$ dotnet --version 5.0.201
まずは動作確認で dotnet new console -o myhello で コンソールアプリケーション myhello を生成してみましょう
~$ dotnet new console -o myhello The template "Console Application" was created successfully. Processing post-creation actions... Running 'dotnet restore' on myhello/myhello.csproj... 復元対象のプロジェクトを決定しています... /home/n-hatano/myhello/myhello.csproj を復元しました (97 ms)。 Restore succeeded.
dotnet run で表示されるところまで確認します
~$ cd myhello/ ~/myhello$ dotnet run Hello World!
PeachPie テンプレートのインストール
次にいよいよ PeachPie をインストールします
dotnet new -i "Peachpie.Templates::*"
これだけです! dotnet new -l コマンドで現在使えるテンプレートの一覧がでます
$ dotnet new -l Templates Short Name Language Tags -------------------------------------------- -------------- -------------- ---------------------- Console Application console [C#],F#,PHP,VB Common/Console Class library classlib [C#],F#,PHP,VB Common/Library * * * ASP.NET Core Empty web [C#],F#,PHP Web/Empty * * *
php で作成可能なのは Console Application と Class library、シンプルな Web アプリの ASP.NET Core Empty の3つになります
PHP で Hello World
まずはコンソールアプリケーションで Hello World を表示する HelloPHP を作成してみましょう
$ dotnet new console -lang PHP -o HelloPHP The template "Console Application" was created successfully.
これだけです。ディレクトリに移って dotnet run してみます
~$ cd HelloPHP/ ~/HelloPHP$ dotnet run HelloPHP says: "Hello World!"
無事実行されました! 生成された PHP のソース Program.php を見てみましょう
<?php function main() { echo "HelloPHP says: \"Hello World!\""; } main();
echo 文1行、ではなくて main 関数を定義するかたちになっています。main 関数は別に必須ではなく echo 1行だけに変更しても問題なく動きます。
Web アプリケーションの作成
MVC ではない素の ASP.NET Core の Web アプリケーションを作成します。PeachPie のドキュメントには
dotnet new web -lang PHP
で作成出来るというように記述されていますが、手元の環境では webapp2 の ASP.NET MVC のテンプレートを探しにいってしまい、それは PHP は対応していないため、上手く作成出来ませんでした。
ここは web ではなく長い名前の “ASP.NET Core Empty” を指定することで作成することが出来ます。
~$ dotnet new "ASP.NET Core Empty" -lang PHP -o HelloWeb The template "ASP.NET Core Empty" was created successfully.
作成されたディレクトリとファイルの構成は以下のようになっていて
├── HelloWeb.sln ├── README.md ├── Server │ ├── Program.cs │ └── Server.csproj └── Website ├── Website.msbuildproj └── index.php
Website ディレクトリに index.php があり、
<?php echo "HelloWeb says \"Hello World!\"";
Server ディレクトリにはコンパイルされた PHP のコードを呼び出す ASP.NET Core の Kestrel を使った Web アプリケーションが配置されています
動かすにはこの Server の方で dotnet run します
~/HelloWeb/Server$ dotnet run info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0] User profile is available. Using '/home/n-hatano/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest. Hosting environment: Production Content root path: /home/n-hatano/HelloWeb/Server Now listening on: http://[::]:5004 Application started. Press Ctrl+C to shut down.
ポート 5004 でリッスンされていますのでブラウザでアクセスしてみます
無事表示されました!
Apache bench で apache(mod_php) と ASP.NET(PeachPie) の速度を比較してみる
最初に Apache での速度を計測します。 Apache は 2.4 PHP のバージョンは 7.4 です
$ apache2 -v Server version: Apache/2.4.41 (Ubuntu) Server built: 2020-08-12T19:46:17 $ php -v PHP 7.4.3 (cli) (built: Oct 6 2020 15:47:56) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
PeachPie が生成した index.php を持つ Website ディレクトリをそのまま apache のドキュメントルートにしました。他はデフォルトです。
使っているマシンのスペックは以下になります
- Ubuntu 20.04
- Core i3-7100U
- メモリ 16GB
apache bench を同時実行を増やしながら行い、実行数 (-n) 100,000 同時実行 (-c) 1000 で残念ながらコネクション数関係と思われるエラーが 10 件発生してしまいました。
このときのスループットも 2700 リクエスト/秒 くらいがピークのようです
$ ab -n 100000 -c 1000 http://127.0.0.1/ * * * Concurrency Level: 1000 Time taken for tests: 36.845 seconds Complete requests: 100000 Failed requests: 10 (Connect: 0, Receive: 0, Length: 10, Exceptions: 0) Total transferred: 19198848 bytes HTML transferred: 2499850 bytes Requests per second: 2714.05 [#/sec] (mean) Time per request: 368.453 [ms] (mean) Time per request: 0.368 [ms] (mean, across all concurrent requests) Transfer rate: 508.85 [Kbytes/sec] received
次に dotnet run で .NET の Kestrel サーバーでの同一条件の性能を測ってみます
Concurrency Level: 1000 Time taken for tests: 17.017 seconds Complete requests: 100000 Failed requests: 0 Total transferred: 23100000 bytes HTML transferred: 2800000 bytes Requests per second: 5876.44 [#/sec] (mean) Time per request: 170.171 [ms] (mean) Time per request: 0.170 [ms] (mean, across all concurrent requests) Transfer rate: 1325.64 [Kbytes/sec] received
エラーなく終了し、スループットも 5800 リクエスト/秒
2倍の性能を出すことが出来ました! これが新型 .NET の性能なのか・・・
今回は MySQL へのアクセスを含んでいませんし、事前コンパイルされるらしい Composer のオートロード周りの処理も確認したわけではなく、あくまで1行 php の性能の比較に過ぎませんので、過信は禁物です。
とはいえ、PHP と MySQL のチューニングにおいてはソケットやセッションといったコネクション周りの問題がボトルネックとなり最大の障害となりますが、同時接続性能の高い .NET はパフォーマンスチューニングの点でも魅力的で、PHP と C# の相互運用が可能になる PeachPie の今後の動向には注目して行きたいと思います
インフィニットループでは PHP や MySQL、インフラの面白い技術を一緒に追求してくれる方々を歓迎しています!
ぜひご応募ください!