Upgrade to Pro — share decks privately, control downloads, hide ads and more …

大解剖!amphpを使って非同期 PHP を実現しよう!

大解剖!amphpを使って非同期 PHP を実現しよう!

PHPカンファレンス2023登壇資料です。

Masaru Yamagishi

October 07, 2023
Tweet

More Decks by Masaru Yamagishi

Other Decks in Programming

Transcript

  1. セッション概要 PHP はデータベース通信、ファイル操作などの I/O バウンドなユースケースで多く使われています。 これまでの PHP では I/O 処理でブロックし、処理が終わるまで待機する仕組みになっていましたが、

    PHP 8.1 から Fiber がコア実装に含まれたことにより、 PHP でも非同期な処理をサードパーティ extension なしでより簡単に実装することが出来るようになりました。 中でも注目を集めるライブラリ群が amphp です。このライブラリ群は、 HTTP サーバや MySQL クエリの 非同期化など様々な高レベル実装を提供しています。 今回は、現段階で実装済みの各ライブラリを紹介し、今後 PHP でも非同期処理を使いやすくなるぞ、と いうことを紹介したいと思います。
  2. もくじ 1. 同期と非同期 a. 同期と非同期 b. 並列と並行 c. Promise と

    Future d. async と await 2. PHP における非同期処理 a. Fiber(イベントループ) b. Revolt c. amphp 3. amphp における非同期処理 4. amphp のユースケース 1. amphp における非同期処理 a. ライブラリ構成図 b. amphp/amp c. amphp/log d. amphp/file e. amphp/socket f. amphp/http-client g. amphp/http-server h. amphp/parallel i. amphp/sync j. amphp/mysql k. amphp/websocket-client l. amphp/websocket-server
  3. 非同期処理における並行 & 並列 非同期処理には種類がある - 並行(Concurrency) - 並列(Parallelism) 言語の仕組みによって並行性が高かったり並列性が高かったりする 言語だけでなくドキュメントでもこの表現は揺れているので、今回の資料では

    - 並行=シングルスレッドでうまいこと非同期する - 並列=マルチスレッド・マルチプロセスで非同期する とする(わかりやすくするため。これが正解というわけではない)。
  4. Promise と Future 非同期な処理の実行を開始した直後は、まだ実行が終わっていないので実行結果を 受け取ることが出来ません。 そこで、 Promise や Future といった「多分まだ終わっていないが、そのうち終わる」プ

    レースホルダーのようなオブジェクトを受け取ります。 このプレースホルダーの名称や挙動は言語やライブラリにより異なりますが、大体「後 で非同期処理結果を取得するためのもの」です。
  5. 何故 PHP は非同期に基本非対応だったか? 元々 PHP を非同期に処理する仕組みは公式には提供されていませんでした。 PHP はあくまで HTML 文字列を随時出力しながら演算する言語だったからです。

    既に出力された文字列はクライアントに見えてしまうので、そこで後で非同期にしてもほ とんど意味がありませんでした。 最近は json でまとめて返すことが増えたので、ユースケースとして現れるようになった 形です。
  6. Revolt Fiber のコールスタックを管理してくれる低レベル API ライブラリ - Defer: go の defer

    のように、イテレーションの最後に - Delay: x 秒後に - Repeat: x 秒おきに - Stream readable: ストリームが読み込めるようになったら - Stream writable: ストリームに書きこめるようになったら - Signal: プロセスシグナルを OS から受け取ったら
  7. amphp が解決する課題 Fiber, Revolt は「ライブラリ作成者向けの低レベル API」です。普段のアプリ開発で直 接利用することはあまり想定されていません。 それらを利用して、アプリ開発レベルまで高レベル化したライブラリが amphp です。

    複数のパッケージとして開発されているライブラリ群で、 async/await のみならず、 HTTP サーバ、 MySQL クエリ、ロギングなど様々な同期処理を非同期化してくれま す。
  8. amphp/amp ベース of ベースとなる中核ライブラリ - v1.0(-2017) は while ループや third-party

    extension を利用した実装 - v2.0(-2022) も同様で、 event-loop を素直に実装したもの - v3.0(2022-) は Fiber(PHP8.1+) を利用したものに大きく変更
  9. ライブラリ構成一覧 - amphp/amp: もちろん全て async な処理 - byte-stream: ストリーム処理 -

    process: 子プロセス - file: ファイル操作 - pipeline: イテレータ - sync: Mutex による同期 - parallel: “並列” 処理 - log: MonologHandler - socket: TCP/UDP ソケット通信 - http-server: TLS, HTTP/2 対応 HTTP サーバ - http-client: TLS, HTTP/2 対応 HTTP クライアント - http-tunnel: Proxy HTTP 通信 - websocket-client: WebSocket クライアント - websocket-server: WebSocket サーバ - redis: Redis 操作 - postgres: PostgreSQL 操作 - mysql: MySQL 操作 - internal: 内部で利用される - sql: SQL の抽象化 - cache: キャッシュの抽象化 - parser: パーサの抽象化 - serialization: シリアライズの抽象化 - http: HTTP 通信の基本実装 - websocket: WebSocket 通信の基本実装 - phpunit-util: PHPUnit サポート - hpack: HTTP/2 用実装
  10. WebSocket による ChatBOT - ロングプロセスモデルで WebSocket client/server の実装 - Slack

    や LINE などのリアルタイム通信を golang や node.js のように - 実装側はほとんど非同期を意識しなくていいので楽 - BotMan のようなフレームワークでそう
  11. Pure-PHP HTTP/2(TLS) サーバ - nginx, php-fpm, apache などを使わず PHP だけで

    HTTP(S) サーバ - TLS や HTTP/2 も対応! - 障害点が減るので嬉しいかも - まだ大規模利用実績はないので、誰かやってみてください(丸投げ)
  12. 大量並行・並列処理のマネジメント - バッチ処理をスケールさせる - クエリをスケールさせる - Cluster や RPC なども開発中

    - 既存の重い処理を一部だけ非同期化して高速化 - パフォーマンスチューニングが捗る