Save 37% off PRO during our Black Friday Sale! »

RoadRunnerの世界 〜 Yet Another Alt PHP-FPM

RoadRunnerの世界 〜 Yet Another Alt PHP-FPM

2021/05/29(土)PHPカンファレンス沖縄2021の登壇資料です

Df4978f14401325586e9e286b140ac4c?s=128

n1215

May 29, 2021
Tweet

Transcript

  1. for PHPカンファレンス沖縄2021 RoadRunnerの世界      ~ Yet Another Alt PHP-FPM 2021年5月29日 (土)

    株式会社Nextat 中榮健二 Nextat Inc. 1
  2. 自己紹介 from 京都 - 中榮健二 (なかえけんじ) - twitter: @n_1215  -

    株式会社Nextat 取締役 - Laravel中心にECサイトやシステム開発 - 最近はFaaS+TSを使ったりUnityを使ったりPHP以外の仕事も増加 Nextat Inc. 2
  3. 発表概要 1. Alt PHP-FPMとは 2. RoadRunnerとは 3. RoadRunnerの設計思想 4. Get

    Started with RoadRunner 5. フレームワーク インテグレーション 6. 利用上のハマりどころ 7. まとめ Nextat Inc. 3
  4. 1. Alt PHP-FPMとは Nextat Inc. 4

  5. 1-1. 従来のPHP製Webアプリケーションの実行方式     PHP-FPM (FastCGI Process Manager) NginxなどのWebサーバと併用 Apache HTTP

    Server mod_php、mod_cgi etc. PHP-FPMとの併用も可 Nextat Inc. 5
  6. 従来のPHP製 Webアプリケーション 1つのHTTPリクエストごとに 状態をリセット 毎回初期化処理を実行する Nextat Inc. 6

  7. 1-2. 従来のPHPのトレードオフ メリット メモリリークを気にしなくて良い HTTPリクエストをまたぐ状態を気にしなくて良い デメリット 毎回初期化するオーバーヘッド とはいえ大抵の場合に充分なパフォーマンスは出せる OPCache、Preloading、JIT HTTPサーバを別途用意する必要がある

    PHPだけでHTTP Serverにはなれない WebSocket Server、gRPC Serverなど長時間実行が必要な用途に向かない Nextat Inc. 7
  8. 1-3. Alt PHP-FPM 従来のPHPとは異なる実行方式を持つ新興のHTTP・アプリケーションサーバを 本資料では Alt PHP-FPM と呼称 Swoole ReactPHP

    Amp PHP-PM (PHP Process Manager) ※ ApacheやLighttpdやIISのことも忘れてませんが、一旦置いておいてください Nextat Inc. 8
  9. Swoole https://www.swoole.co.uk/ コルーチンベースの非同期並行実行ライブラリ(PHP拡張/C言語) PHPのコードでHTTPサーバやWebSocketサーバを実装することが可能 Coroutine、Fiber API 中華圏での採用実績 対応フレームワーク多数 Nextat Inc.

    9
  10. ReactPHP https://reactphp.org/ PHPのイベント駆動プログラミングのライブラリ HTTPサーバやWebSocketサーバが実装可能 EventLoop、Promise、Stream イベントループはNode.jsと同じReactorパターンを利用 Nextat Inc. 10

  11. PHP-PM (PHP Process Manager) https://github.com/php-pm/php-pm PHPアプリケーションのプロセスマネージャ、ロードバランサ ベースにReactPHPを利用 子プロセスでPHPをWorkerとして動かす Symfony/Laravelなどに対応 Nextat

    Inc. 11
  12. Amp https://amphp.org/ イベント駆動な並行処理のフレームワーク Event Loop、Promise、Coroutine、Stream PHPのコードでHTTPサーバを実装可能。HTTP/2対応 Streaming対応gRPCサーバも実装できそう(過去の発表でお世話になった) Nextat Inc. 12

  13. HTTPサーバの例 (React) https://reactphp.org/ $loop = React\EventLoop\Factory::create(); $server = new React\Http\Server(

    $loop, function (Psr\Http\Message\ServerRequestInterface $request) { return new React\Http\Message\Response( 200, ['Content-Type' => 'text/plain'], "Hello World!\n" ); } ); $socket = new React\Socket\Server(8080, $loop); $server->listen($socket); $loop->run(); Nextat Inc. 13
  14. 毎回の初期化処理を省略できる Nextat Inc. 14

  15. 2. RoadRunner https://roadrunner.dev/ Nextat Inc. 15

  16. Nextat Inc. 16

  17. RoadRunner     https://roadrunner.dev/ 2018年リリース Golang製のPHPアプリケーションサーバ 開発元は Spiral Scout 、開発者は Anton

    Titov 氏 Nextat Inc. 17
  18. 前面のGoサーバがリクエストを受け付け、PHPのWorkerに振る構成   https://roadrunner.dev/docs/intro-about より Nextat Inc. 18

  19. 特徴 ワンバイナリでクロスプラットフォームで動く HTTPサーバ(HTTP/2対応、静的ファイル配信可) gRPCサーバ(今の所PHPで書けるのはUnary RPCのみ) FastCGIにも対応 PHP拡張なしで利用できる Goによるカスタマイズが可能 PHPからGoのサービスへのRPCが可能 PHPのWorkerはPSR-7に標準対応

    プラグインで機能拡張可能 Nextat Inc. 19
  20. パフォーマンス https://roadrunner.dev/features より 注1: RoadRunnerが目立つが、NGINX Unitの性能も凄いのでは 注2: Swooleが入っていないがSwooleのほうが速いだろうとのこと 参考: https://youtu.be/mj6d-IGzSYE?t=2335

    Nextat Inc. 20
  21. 3. RoadRunnerの設計思想 従来の実行方式との違いと他のAlt PHP-FPMとの比較 Nextat Inc. 21

  22. ブログ記事: PHP is meant to die (2013/04) https://software-gunslinger.tumblr.com/post/47131406821/php-is-meant-to- die Nextat

    Inc. 22
  23. Software Gunslinger - PHP is meant to die 著者はPHP4の頃から10年以上の経験を持つPHP開発者 PHPという言語が滅ぶべくして滅ぶ、という話ではない

    PHPは実行がすぐ終わる(= die)ことを前提に設計されている 合わない使い方はするなよ、という話 WebSocketやキューワーカーのためにバックグラウンドでのコード実行したい だが、PHPをデーモン化する(Summon the daemons)とメモリリークな ど問題発生 Python + Flask + Supervisor + Gunicornの構成に感銘を受けたらしい Nextat Inc. 23
  24. Software Gunslinger - PHP is meant to die, continued 前記事の補足記事

    (現時点では)継続的に実行させるプロセスにPHPは向いていない、という主旨 ReactPHPの検証 メモリーリークの問題、安定性の問題 ReactをWorkerで実行する方法なら望みはあるかも、という事も書いてある Nextat Inc. 24
  25. Can a long-living php application be pragmatic? Nextat Inc. 25

  26. RoadRunnerの開発者 https://github.com/wolfy-j Anton Titov 氏 (a.k.a Wolfy-J) Spiral Scout CTO・共同創業者。Twitter

    @lachezis 日本語Tweetにも「それRoadRunnerで出来るよ」とリプをくれるナイスガイ RoadRunnerに関するツイートは全て補足されている模様 本資料の大半は氏の発表資料、動画を参考にしています Nextat Inc. 26
  27. PHPアプリケーションの高速化という課題 初期化を前倒ししたい ライフサイクルの長いPHPスクリプトの実行が必要 Nextat Inc. 27

  28. 既存のAlt PHP-FPMの比較と考察 RoadRunner (スライド・ロシア語) https://docs.google.com/presentation/d/1YnymGamkustDeujhTJhyTN h9_UtayV7quzF-4H3W0tU PHPKonf 2020 - Anton

    Titov: Designing hybrid Go/PHP applications using RoadRunner(動画・英語) https://www.youtube.com/watch?v=mj6d-IGzSYE Nextat Inc. 28
  29. 既存の有力な選択肢のアプローチは二種類 ノンブロッキング シングルプロセスで多重リクエストを処理 メモリ消費量の低減 コンテキストスイッチによるオーバーヘッドなし Reactorパターン コールバック地獄になるが、Promiseなどで解消 既存のPHPのノンブロッキングではないライブラリとの相性が良くない ex) Node.js、EventMachine(Ruby)、Twisted(Python)

    Nextat Inc. 29
  30. ブロッキング マルチプロセス 既存のライブラリ、SPLを普通に使える メモリリークの可能性 コンテキストスイッチやプロセス間通信のコスト Nextat Inc. 30

  31. 既存の選択肢 ReactPHP ノンブロッキング Promise すぐに使える、大規模コミュニティ、PHPで書かれている サーバとアプリケーションが同じPHPのプロセス Nextat Inc. 31

  32. Swoole ノンブロッキング 2系からコルーチン コルーチン、超高速、大規模コミュニティ(中華圏) サーバとアプリケーションが同じPHPのプロセス、Windows非対応 Nextat Inc. 32

  33. Amp ノンブロッキング Promise, コルーチン すぐに使える、PHPで書かれている サーバとアプリケーションが同じPHPのプロセス Nextat Inc. 33

  34. PHP PM ブロッキング マルチプロセス すぐに使える、コミュニティ、サーバとアプリケーションが別プロセス 遅い、メモリリーク、Windows非対応 Nextat Inc. 34

  35. 既存の選択肢では求める条件に合わなかった サーバ自体のプロセスはPHPではないほうが良い 既存のライブラリやFWをそのまま使いたい どこでも動く ハイパフォーマンス Nextat Inc. 35

  36. 新しいアプリケーションサーバを作る 目標 既存の数あるFWとの互換性 サーバプロセスとPHP Workerが別プロセス ハイパフォーマンス、安定性、エラーハンドリング PHPをビルディングブロックとして使うためのHTTPサーバ以上のなにか どこでも動く アーキテクチャを最小のオーバヘッドで用意に拡張 Nextat

    Inc. 36
  37. サーバプロセスの選択 Golang Spiral Scoutは2016年頃Golangを開発スタックに導入した 高速なアプリケーションが設計可能であると実感 軽量な並行処理の道具立て goroutine: ユーザ空間で動く軽量スレッド channel: マルチスレッドだが直接のメモリアクセスを行わないことを推奨

    Nextat Inc. 37
  38. PHPとのGoのプロセス間通信の選択肢 既存のもの 素晴らしいライブラリ deuill/go-php がすでにあったが合わなかった PHPのカスタムビルドが必要。設定が難しい 共有メモリ OS依存 ポテンシャルは高いが扱いが難しい ソケット/パイプを介したバイナリストリームによる通信

    古典的で実績のあるアプローチ こちらを採用 Nextat Inc. 38
  39. Goridge https://github.com/spiral/goridge Pipe、UNIX/TCP Socketで動作 小さいオーバーヘッド PHP側に追加の拡張は不要 副産物として、PHPからRPCでGoのサービスを呼び出すことが可能になった Nextat Inc. 39

  40. Goridgeの実装に利用されたパッケージ Golang バイナリの扱い: encoding/binary 標準入出力: io UNIX, TCP: net PHP

    バイナリの扱い: pack(), unpack() 標準入出力: 組込みのストリーム Unix, TCP: 組込みのソケット Nextat Inc. 40
  41. HTTPスタック Goの net/http のHTTPリクエストをPHPに渡す際に PSR-7 のリクエストに変換 プロセスマネージャ、ロードバランサ 時間の都合で割愛 詳細は前述のPHPKonf 2020の動画を参照

    Nextat Inc. 41
  42. ブログ記事: PHP was never meant to die https://spiralscout.com/blog/php-was-never-meant-to-die PHP is

    meant to die に 対するアンサーを意識した題名 従来のPHPの課題と非効率性 既存のAlt PHP-FPMの選択肢への不満 RoadRunnerの設計の概要 負荷がスパイクする環境のNginx、PHP-FPMをRoadRunnerに置換 502エラーを解消し、サーバを3分の2に減らせた Nextat Inc. 42
  43. 4. Get Started with RoadRunner Nextat Inc. 43

  44. インストール $ composer require spiral/roadrunner:v2.0 nyholm/psr7 $ ./vendor/bin/rr get-binary $

    chmod 744 rr 現在の最新版は 2.2.1 requires PHP >= 7.4 PSR-7の実装パッケージが必要(ここでは nyholm/psr7) 1系ではLaminas(Zend) Diactorosに依存していたが取り除かれた Composerでインストールし、コマンドを使ってバイナリをDL ※ DL時にサンプルの設定ファイルを生成するかどうか尋ねられるがNoで良い Nextat Inc. 44
  45. 設定ファイル .rr.yaml rpc: listen: tcp://127.0.0.1:6001 server: command: "php worker.php" http: address:

    "0.0.0.0:8080" pool: num_workers: 4 https://roadrunner.dev/docs/intro-config の 最小構成を参照 Nextat Inc. 45
  46. PHP Worker のエントリポイント worker.php <?php use Spiral\RoadRunner; use Nyholm\Psr7; include

    "vendor/autoload.php"; $worker = RoadRunner\Worker::create(); $psrFactory = new Psr7\Factory\Psr17Factory(); $worker = new RoadRunner\Http\PSR7Worker($worker, $psrFactory, $psrFactory, $psrFactory); while ($req = $worker->waitRequest()) { try { $rsp = new Psr7\Response(); $rsp->getBody()->write('Hello world!'); $worker->respond($rsp); } catch (\Throwable $e) { $worker->getWorker()->error((string)$e); } } Nextat Inc. 46
  47. サーバを起動 ディレクトリ構成 起動コマンド $ ./rr serve http://localhost:8080 にアクセスするとHello, world! が表示される

    Nextat Inc. 47
  48. おまけ: Docker環境 Spiral ScoutのRoadRunnerのDockerイメージ https://hub.docker.com/r/spiralscout/roadrunner ローカル開発用のDocker環境スケルトン (手前味噌ですが) https://github.com/n1215/roadrunner-docker-skeleton Docker ComposeとBashが必要

    $ git clone https://github.com/n1215/roadrunner-docker-skeleton.git your_app $ cd your_app $ ./task init $ ./task up Nextat Inc. 48
  49. 5. フレームワーク インテグレーション Nextat Inc. 49

  50. 多くのFWに対応 (サードパーティ多め) CakePHP https://github.com/CakeDC/cakephp-roadrunner Laminas Mezzio https://github.com/bcremer/roadrunner-mezzio- integration Laravel https://github.com/spiral/roadrunner-laravel

    Slim https://github.com/tanakahisateru/rr-slim Symfony https://github.com/baldinof/roadrunner-bundle Symlex https://github.com/symlex/symlex Yii https://forum.yiiframework.com/t/using-roadrunner-as-a- server/127060 PSR-7を使っているものだと接続が簡単 Symfony HTTP Foundation系列はPSR-7ブリッジを併用 Nextat Inc. 50
  51. Laravel Octane https://github.com/laravel/octane Laravel公式のパッケージ 高性能なアプリケーションサーバでパフォーマンスを向上 Swoole または RoadRunner この機会にRoadRunnerも流行って欲しい 今現在はSwoole限定の機能が多い?

    Swoole Tables を使ったキャッシュなど Nextat Inc. 51
  52. Spiral Framework https://spiral.dev/ Spiral Scout謹製。RoadRunner前提のFW ControllerやHTTP層の処理自体は他のFWとほぼ変わらず 注目すべきコンポーネント(独断) Cycle ORM: DoctrineライクなORM

    ジョブキュー: 開発用にはRoadRunner単体で利用できる WebSocket Temporal 連携: ワークフローエンジン Nextat Inc. 52
  53. Goで書けるならGoで拡張していこうというスタイル 重いHTTP MiddlewareをGo側に移す JWTの検証 Goのライブラリを使って書いたサービスをPHPからRPCで使う Goridgeの恩恵 Goで書いた場合はRoadRunnerの自前ビルドが必要になる Nextat Inc. 53

  54. 6. 利用上のハマりどころ Nextat Inc. 54

  55. (1) メモリリーク RoadRunnerは利用メモリが多くなったWorkerを入れ替える設定も可能 だが、当然メモリリークがないほうが良い 注意してコードを書くと共に、信頼できるFWやライブラリを使うことも重要 (2) グローバルな状態の汚染 global、static変数の変更が共有される Worker間での状態の共有はないが、Worker内ではリクエストをまたぐ ログインユーザやセッションがリクエストをまたいで共有される恐怖

    DI・サービスコンテナの中身、シングルトン HTTPリクエストやHTTPリクエストから導出されるものはコンテナに保持し ないのが簡単 もしくはリクエスト毎のスコープでオブジェクトを保持できるようにする Nextat Inc. 55
  56. (3) リソースのロック 開いたリソースをすぐ閉じるのが基本 DBコネクションを監視 リクエストをまたぐファイルロックを避ける その他の注意事項はドキュメントを参照 Caveats Production Usage 他のAlt

    PHP-FPMに比べると少なめな印象 Nextat Inc. 56
  57. 7. まとめ Nextat Inc. 57

  58. まとめ Alt PHP-FPMはPHPアプリケーションサーバの新潮流 初期化の前倒しによってパフォーマンスの向上が見込める PHPの長時間実行により、WebSocketやgRPCサーバの実装も可能 PHP-FPMからの移行先としてRoadRunnerは優しい選択肢の一つ PHP-FPM向けに比較的近い感覚でコードを書くことができる 普段のPHP開発よりグローバルな状態やメモリリークへの配慮が必要 同じ開発元のSpiral Frameworkを始め、フレームワークとの統合も進む

    用途があえばぜひ利用してみてください Nextat Inc. 58
  59. 蛇足 gRPCサーバの改善を予定しているようです。期待 ※ 現状PHPだけで書けるのはUnary RPCのみ たまに出てくるロシア語はGoogle翻訳などを使って読もう 記号にしか見えない (゚Д゚) 英語のほうが素直に変換される Nextat

    Inc. 59
  60. 参考資料 RuadRunner公式サイト https://roadrunner.dev RoadRunner (スライド・ロシア語) https://docs.google.com/presentation/d/1YnymGamkustDeujhTJhyTN h9_UtayV7quzF-4H3W0tU PHP fwdays 2019

    - Anton Tsitou "Designing hybrid Go/PHP applications using RoadRunner"(スライド・ロシア語) https://www.slideshare.net/fwdays/anton-tsitou-designing-hybrid- gophp-applications-using-roadrunner PHPKonf 2020 - Anton Titov: Designing hybrid Go/PHP applications using RoadRunner(動画・英語) https://www.youtube.com/watch?v=mj6d-IGzSYE Nextat Inc. 60
  61. PR: 開発者を募集しています 株式会社Nextat nextat.co.jp 受託開発 業務システム、ECサイト、スマホアプリ... 本社は京都ですが、東京・名古屋などリモートワーク実績あり 設計の話に付き合ってくれる方大歓迎! Nextat Inc.

    61
  62. アピールポイント RoadRunnerのサイトに弊社の記事のリンク Nextat Inc. 62

  63. ご清聴ありがとうございました Nextat Inc. 63