9.2K Views
March 21, 25
スライド概要
本日のテーマ PHPの実行環境の発展から見る 「プロセス分離型」と「Webサーバー統合型」の遷移 1. Apache + CGI + PHP 2. Apache + mod_php 3. Nginx + php-FPM 4. FRANKENPHP
PHP実行環境の歴史 PHP-FPMからFrankenPHPの誕生へ 2
自己紹介 HN:ma_me(twitterも同じ) Webエンジニア歴:10年ちょい 主な言語: 所 属:
簡単な用語説明 より理解を深めてもらうために、 頻繁に出てくる用語の簡単な概要説明 1.CGI 2.プロセス 4
CGIの概要説明 1. Common Gateway Interface • よくCGIと呼ばれるもの • Apache, NginxなどのWebサーバーと スクリプト言語間(例:PHPなど)で データを受け渡すための標準的なインターフェース 5
CGIのRFC RFC 3875 - The Common Gateway Interface (CGI) Version 1.1 6
プロセスのざっくり概要 2. プロセス OS が管理する実行単位 • 親(メイン)プロセス • 子(サブ)プロセス が存在する 親が落ちると子も落ちる 7
プロセスのざっくり概要 ブラウザ:親プロセス タブ:子プロセス 注)本当はブラウザのプロセスはもっと複雑です。説明のため省略 8
前置き終了 9
Apache 1: Apache + CGI + PHP
Apache + CGI + 時代背景 • 仮想化技術が未発達 • 一台のサーバーで どれだけリクエストを捌けるかが勝負の時代 Apacheの特性 • 1リクエストに対して1プロセスを生成するPre-Fork型 • プロセス数 > CPUのコア数になると、処理待ちが発生する 11
Apache + CGI + プロセス分離 1. Apache(mod_cgi) 2. PHP(php-cgi) Apach側がPHPをCGI経由で呼び出す 「プロセスを分離」 Apache 12
Apache + CGI + プロセスのフロー PHPプロセス生成 処理結果を返却 (php-cgi) 13
Apache + CGI + 構成のメリット •ApacheとPHPが疎結合で お互いのバージョンや設定に影響を受けにくい •Apacheから見た場合 CGI実装であればPHP以外でも差し替えれた 14
Apache + CGI + リクエストのたびに - Apacheが1プロセスを利用 –PHPプロセスが生成・破棄される 構成のデメリット 高コスト (CPU & メモリ負荷が高い) ~ ~ 破棄PID:12346 NewPID:12347,12348 15
Apache + CGI + 構成のデメリット 高コスト 「Webサーバー統合」の リクエストのたびに - Apacheが1プロセスを利用 –PHPプロセスが生成・破棄される (CPU & メモリ負荷が高い) アプローチで、解決 → Apache + mod_phpへ 破棄PID:12346 ~ ~ NewPID:12347,12348 16
Apache 2. Apache + mod_php (PHP Module)
Apache mod_php 時代背景 かわらず • 仮想化技術が未発達 • 一台のサーバーで どれだけリクエストを捌けるかが勝負の時代 Apacheの特性 • 1リクエストに対して1プロセスを生成するPre-Fork型 • プロセス数 > CPUのコア数になると、処理待ちが発生する 18
Apache mod_php Webサーバーに統合 Apacheにモジュールとして、PHPを統合した =mod_php 実装言語がC同士なので、比較的容易だった 実装言語 Apache 19
Apache mod_php イメージ Apache + CGI + PHP (プロセス分離のアプローチ) Webサーバー統合のアプローチ (Apache + mod_php) (php-cgi) Apache (mod_php) 20
Apache mod_php プロセス Apache + CGI + PHP ~ Apache + mod_php ~ Apacheだけに phpのプロセスは無くなった 21
Apache mod_php メリット •CGIのオーバーヘッドがなくなり、 処理が高速化 •1リクエストごとの PHPプロセスの生成・破棄が無くなった 22
Apache mod_php デメリット •すべてのリクエストに PHP モジュールが付随 例:HTML・画像など •メモリ使用量の増大とスケーラビリティ低下 23
Apache mod_php デメリット メモリをより大量に消費しやすい環境に 増 同時接続を処理する際のスケーラビリティ問題が発生 C10k問題の発生確率 24
Apache mod_php デメリット メモリをより大量に消費しやすい環境に 再び「プロセス分離」 C10k問題の発生確率 増 することで、解決へ → Nginx + PHP-fpmへ 同時接続を処理する際のスケーラビリティ問題が発生 25
Nginx + PHP-FPM
+ 時代背景 • クラウド技術の発展とともに仮想化が進み、 コンテナ(Docker など)が定着 • Nginx がイベント駆動型のアーキテクチャを採用 Apache の Pre-Fork 方式と比べてスケーラビリティが向上 • C10k問題から、高負荷環境やコンテナ環境で Nginx の採用が加速 27
改良点 イベント駆動アーキテクチャ Pre-fork型(従来のApache) イベント駆動型(Nginx) 同期的・ブロッキング 非同期・ノンブロッキング 1プロセス・1リクエスト 1プロセス・複数リクエスト プロセスごとにメモリを多く消費 リソースを効率よく使用 c10k問題(大量の同時接続処理)にも 対応しやすい 28
補足 今ではApache も イベント駆動に対応している Apacheはイベント駆動への取り組みがNginxと比べて遅かった 今では様々な実行形式を選べるようになっている 現在選択できるMPM 1. event(イベント駆動形式) 2. prefork(旧来の形式) 3. worker(マルチプロセス・マルチスレッド形式) 29
補足 今ではApache も イベント駆動に対応している • スライドではスペースの都合上、Nginxで表記 • 現在ではphp-fpm なら Nginxではなく php-fpm なら Apache でも Nginx でも可能 Apache OK OK 30
改良点 PHP FastCGI Process Management •FastCGI CGIが進化したFastCGIを採用して、CGI の欠点を克服した •Process Managementの独立 PHP のプロセス管理を独立させた 31
php-fpm(FastCGIの実装) による改良点 通信方式 プロセス管理 レスポンス 環境変数 CGI FastCGI 改良点 1リクエスト = 1プロセス プロセスを再利用 高速化 & 負荷軽減 一括送信 ストリーミング可能 リアルタイム処理可能 使用する 使用しない (バイナリパケット) OS の制限を回避 環境変数 + stdin/stdout バイナリプロトコル (ソケット通信) データ転送効率向上 32
Process Managementの独立 ps -a ~ php-fpm.d/www.conf [www] user = www-data group = www-data listen = 127.0.0.1:9000 pm.max_children = 5 pm.start_servers = 2 (pm=プロセスマネージャーの略) 33
プロセス再利用のイメージ ~ ~ 34
+ 改善点 プロセスの再利用による効率化 ➡ 1つのプロセスを複数のリクエスト処理に活用 プロセスの生成を最小限に抑制 ➡ より少ないリソースで多数の接続を処理可能 非同期処理によるスケーラビリティ向上 ➡ 高負荷環境でもスムーズに動作 35
+ 改善点 プロセスの再利用による効率化 ➡ 1つのプロセスを複数のリクエスト処理に活用 今でも長く使われる 環境に 非同期処理によるスケーラビリティ向上 プロセスの生成を最小限に抑制 ➡ より少ないリソースで多数の接続を処理可能 ➡ 高負荷環境でもスムーズに動作 36
ここまでの遷移まとめ
ここまでの遷移まとめ プロセス分離:Apache+CGI+PHP → Webサーバー統合:Apache+mod_php → プロセス分離:Nginx(Apache)+ php-fpm → ???(次は?) 38
ここまでの遷移まとめ プロセス分離:Apache+CGI+PHP → Webサーバー統合:Apache+mod_php → プロセス分離:Nginx(Apache)+ php-fpm → Webサーバー統合: 39
Franken PHP 40
時代の遷移 時代が進むにつれて、コンテナ技術が進化・普及した • 1つのWebアプリケーションに対して 複数台のコンテナを利用することが当たり前になった • スケーリングの切り替わり 垂直方向 (1台のパフォーマンスを増強)の拡張から 水平方向 (台数を増やして負荷分散)の拡張へ 41
+ デメリット PHPでWebサービス作る時の最低限のセット数 1. php-fpm 2. Webサーバー 3. DBサーバー 3台はコンテナが必要 最低限 DB 設定ファイル 設定ファイル port:×× port:△△ port:〇〇 42
+ デメリット 水平スケールする時に 1. 各コンテナ・サービスの設定ファイル 2. 各コンテナ間のファイル同期 3. 各コンテナ間のポート調整 4. 各コンテナ間の通信調整 (1~4)*N回必要 かつ コンテナ間の管理がより煩雑に 43
+ デメリット 水平スケールする時に 1. 各コンテナ・サービスの設定ファイル もっと単純に 3. 各コンテナ間のポート調整 4.かつパフォーマンスを出そう! 各コンテナ間の通信調整 → FrankenPHPへ 2. 各コンテナ間のファイル同期 (1~4)*N回必要 かつ コンテナ間の管理がより煩雑に 44
Franken PHPとは Go言語製のWebサーバー Caddy •CaddyにPHP実行環境を組み込み、 PHPの実行環境を備えたWebサーバー •PHPのプロセスはCaddy内部で直接処理されるため FastCGIプロトコルを使用しない 45
特徴 •Go 言語で実装されいて、 組み込みのマルチスレッド & 非同期 I/Oに強い •ゴルーチンによる非同期処理と 効率的なマルチスレッド処理を活用して、 高並列なリクエスト処理が可能 •後発なだけあって、ApacheやNginxより高性能 (Go言語に強くないので、サイトの引用) 46
FrankenPHPにおける PHPの立ち位置 直接Webサーバーに統合 php-fpmも利用しないし、FastCGIも実装していない 未使用 統合 FastCGI 47
FrankenPHPにおける PHPの立ち位置 直接Webサーバーに統合 php-fpmも利用しないし、FastCGIも実装していない php-fpmもFastCGIも使わない 未使用 既視感があるアプローチ 統合 FastCGI 48
アプローチ比較 Apache + mod_php もとった Webサーバーに統合するアプローチ (mod_php) 49
Franken PHPの黒魔術 Apache + mod_phpの場合 ベースが同じC言語なので組み込みやすい 実装言語 mod_php 実装言語 50
Franken PHPの黒魔術 Franken PHPの場合 言語が違うのに、どうやって組み込む? 実装言語 ? 実装言語 51
Franken PHPの黒魔術 GolangのコードからC言語のコードを呼び出すことが可能 Golangが持つ 「cgo」というメカニズム 52
Franken PHPの黒魔術 もしかしてC言語で実装されたPHPも cgoで直接呼び出せるのでは? 実装言語 ??? 53
魔術 完成の瞬間 黒 出典:FrankenPHP: A modern app server for PHP, written in Go - Speaker Deck 54
魔術 完成の瞬間 黒 これは確かに Franken(stein) 出典:FrankenPHP: A modern app server for PHP, written in Go - Speaker Deck
誕生 誕生 56
何故インターフェースを かまさないのか? 中々無茶なことをやっているように見えます • APIやCGIを経由する • 別サービスに切り出す • etc 何らかのインターフェースを嚙ますことが1つの解決策 何故そうしないのか? では 57
Q&A A:何らかのインターフェースを介 すると サーバーやコンテナの構成など、 いろんな面で複雑になるから (例:PHP-FPM) 出典:FrankenPHP: A modern app server for PHP, written in Go - Speaker Deck 58
Q&A 組み込んで柔軟性を捨てたことで どれだけのメリットを得られたかが大切 59
どれだけメリットを得られたか caddyに組み込んでいるため、直接やり取りできる caddyの持っている機能・メリットを全部享受することに成功 Caddyのメリット 1.非同期I/O、イベント駆動アーキテクチャ 2.103 Early Hints status code 3.HTTP2,3(Quick)標準対応 4.JSライブラリやSDKは不要のイベントプッシュ etc… 60
どれだけメリットを得られたか そして何より 1. コンテナが1つで済む 2. 設定が楽 Webサーバー PHP 61
組み込んだデメリット 1.Webサーバーと蜜結合ゆえに実質Apache or Nginxから乗り換えることになる 2. 付随して、学習コストや情報源の問題が発生 3. プロダクト採用実例も殆どない このメリット デメリットを どう感じるかが、採用の決めて 62
余談
プロセス分離と Webサーバー統合を比較して プロセス分離の特徴 依存関係を制御し、変化に強い設計で、 長年使えるソフトウェアを創る Webサーバー統合の特徴 深いモジュールで複雑さを封じ込め、 使用者に単純さを提供する 64
既視感 どちらのアプローチが好きですか? 65
個人の感想 めっちゃ好き 66
まとめ
まとめ アーキテクチャ分類 プロセス分離型 サーバー統合型 mod_php CGI 安定性 プロセス分離型 サーバー統合型 高い 低い スケーラビリティ 高い 設定 複雑 デプロイの複雑さ 複雑 低い 簡易 簡易 68
どれがハイパフォーマンスなのか? FrankenPHPがどこまでパフォーマンスが出せるのかは 試せていない… 次回機会があれば、各構成のパフォーマンス比較検証したい VS VS 69
最後に宣伝
PHPエンジニアを絶賛募集中 採用情報 | https://booost-tech.com/recruit
ご清聴ありがとうございました