これを読んでも、非同期処理はわかりませんが、暗いトンネルの先に光が見えます。
@hanhan1978PHPで書いて覚える非同期処理PHPカンファレンス 2021
View Slide
@hanhan1978● 富所 亮● 所属○ 株式会社カオナビ● 職業○ Webアプリケーションエンジニア● ブログ○ https://blog.hanhans.net● Yokohama North AM○ https://anchor.fm/yokohama-north-am2
はじめに3
4PHPアプリケーションは同期的なBlocking IOが基本
5私達が書いたプログラムは書いた順番に処理されて動作する人間の脳にとてもやさしい
6非同期は、分かりにくい界隈では、関連情報が増加してきているのは感じるSwoole, React, AmPHP…. Generator, Fiber
7書いたプログラムは書いた順番に動くとは限らない人間の脳にとても厳しい
8今回のテーマ
9「非同期が分からない!」を分解
10今日のテーマ
11裏テーマ
12システムコールとか、Socket通信とかをPHPで書こうと思う人を増やす
13Webサーバーが作れるようになるぞ!https://speakerdeck.com/hanhan1978/phpdewebsabazuo-rou
PHPでPHPを動かす時代が来る!14多分
小ネタ平行じゃない => 並行平行 : parallel並行 : concurrent, (parallel)並列 : parallel15
1. 用語の定義2. なぜ必要なのか?3. 非同期関連の実装4. PHPで使える解決策目次16
同期的なプログラミング記述したとおりの順番で動作するようなプログラミングモデル非同期プログラミング独立して発生するイベントに対する処理を記述するための並行プログラミング手法の総称17高野祐輝. (2021). 並行プログラミング入門 5章 (初版.). オライリー・ジャパン.
同期的なプログラミング記述したとおりの順番で動作するようなプログラミングモデル非同期プログラミング独立して発生するイベントに対する処理を記述するための並行プログラミング手法の総称18高野祐輝. (2021). 並行プログラミング入門 5章 (初版.). オライリー・ジャパン.処理の順番はイベントの発生順に依存する
19Async Programming - ColdBox HMVC Documentationhttps://coldbox.ortusbooks.com/digging-deeper/promises-async-programming
20Async Programming - ColdBox HMVC Documentationhttps://coldbox.ortusbooks.com/digging-deeper/promises-async-programmingタスクは直列に実行されるため、全ての処理を足し合わせた実行時間になる
21Async Programming - ColdBox HMVC Documentationhttps://coldbox.ortusbooks.com/digging-deeper/promises-async-programmingタスクは並列に実行されるため、全体の処理時間≒ 最も長いタスクの時間
22例えばPHP
23ToDoリストを検索するバックエンドの処理(例)
24ToDoリストを検索するバックエンドの処理(例)直列に処理しなければ、整合性が取れない。同期的処理に意味がある
25例えばJavaScript
26buttonクリックで発生するイベント
27buttonクリックで発生するイベントボタンがいつ押されるかは分からない。非同期的処理に意味がある
28例えばJavaScript - part2
29ページ読込み後にAjaxでAPIをコールする例
30buttonクリックで発生するイベント付帯情報は、あとでページに表示されれば問題ない非同期的処理に意味がある
改めて比べてみると向き・不向きに合わせてプログラミングモデルが選択されているだけ31特にJavaScriptは、処理をブロックしないことに心血を注いでいる
32小ネタ2JSの人たち「たまには同期してほしい」PHPの人たち「たまには非同期してほしい」
1. 用語の定義2. なぜ必要なのか?3. 非同期関連の実装4. PHPで使える解決策目次33
34JavaScriptで考えてみる
35Amazon トップページ
36Amazon トップページ各要素は、スクロールに合わせて読み込まれる非同期であることがUX向上にダイレクトにつながる
JSの非同期処理の実行モデル37https://zenn.dev/qnighy/articles/345aa9cae02d9d
38PHP(バックエンド)で考えてみる
39いわゆるMVCフレームワーク
40いわゆるMVCフレームワーク1. 認証して
41いわゆるMVCフレームワーク2. 過去の参加イベントを取る
42いわゆるMVCフレームワーク3. メインに表示する情報を取得
43非同期にしてしまうと、事前に必要なデータが取れていない。同期的であることに意味があるパターンが多い。
44バックエンドのひとつのエンドポイントから考えると、非同期処理の必要性が分からなくなる
45うまく適用できた例
46https://speakerdeck.com/suzuki/guzzle-promisewoshi-tuta-fei-tong-qi-chu-li-niyoruapikorufalsegao-su-hua
47https://www.slideshare.net/techblogyahoo/phpioyield-phpcon2014
48同時に実行しても問題ないIO処理を束ねる
49その他の適用例
50Queue
51Laravel Queues [ Pocket Guide ] - DEV Communityhttps://dev.to/mvpopuk/laravel-queues-pocket-guide-c6a
52イベント監視が別プロセスだけど...メール送信、退会バッチ処理等、適用範囲も広い。長いIOを他のプロセスにまかせてしまい結果をすばやく戻す
53PHP単体だと、非同期処理は適用範囲が狭い
54なぜ非同期フレームワークは生まれなぜFiberは実装されるのか
55視野を広げてみる必要がある
56いわゆる PHP のWebアプリ
57Nginx + PHP-FPMPHP処理系の気の効いた図
1リクエストに対して 1つのPHP実行プロセス58
1リクエストに対して 1つのPHP実行プロセス59各リクエストは、隔離されたプロセスで実行され、互いに影響しない
60既存のPHPの処理モデルは同期的、ステートレス
61例えば、Swoole PHP
Swooleサーバーの概要図62
Swooleプロセス自体が1つのPHPプロセス63
Swooleプロセス自体が1つのPHPプロセス64各リクエストは、同じプロセス内で実行される。コルーチンで分離されている
65Swoole が非同期で目指すこと1つのコルーチンがIO処理待ちになったら、次のコルーチンに処理を移すCPUの利用効率をあげる。
66Swoole が目指すのは非同期的でステートフルな処理モデル
67しかし、エンドポイント単位の視点に立つと-> リクエストは同期的に処理されているようにみえる
68だから、PHPerには非同期処理がわかりずらい。
1. 用語の定義2. なぜ必要なのか?3. 非同期関連の実装4. PHPで使える解決策目次69
この章はPHPで非同期実装の感覚を養う話70
71PHP単体での非同期処理の仕組みはない(多分)システムコールと組み合わせて、非同期に処理を行う実装を行う
72ここで、ちょっとだけ事前説明
73システムコールオペレーティングシステム (OS)(より明確に言えばOSのカーネル)の機能を呼び出すために使用される機構のこと。
74Socket Functionshttps://www.php.net/manual/en/ref.sockets.php
75Socket通信
76https://world4java.wordpress.com/2014/02/28/socket-programming/Socket Programming
77IOモデル
78● ブロッキング IO● ノンブロッキング IO● IO 多重化● シグナル IO● 非同期 IO
79● ブロッキング IO● ノンブロッキング IO● IO 多重化● シグナル IO● 非同期 IO ← この2つは今日は扱いません
80IOモデルを文章だけで理解するのは難しいので...
81Echoサーバー
82文字列を受け取って、文字列を返すだけのサーバー
83文字列を受け取って、文字列を返すだけのサーバーechoサーバーに接続
84文字列を受け取って、文字列を返すだけのサーバー入力した文字列がそのまま戻ってくる
85Echoサーバー実装は、非同期処理関連の実装技術を知るための、極めて効果的でコスパが高い方法写経をオススメします!!
86https://speakerdeck.com/bati11/otozhong-liang-kunaruhuaC言語の実装例本当はコレを写経するのが良いが...
PHPでの実装例87https://github.com/hanhan1978/shadow-php/tree/master/echo-server
88Blocking IO
89
90ブロッキングIO
91ブロッキングIOSocketでListen
92ブロッキングIOここでBlock
93ブロッキングIOこのサーバーは、通信をBlockするので、一度に1クライアントしか扱えない
94NonBlocking IO
95
96ノンブロッキングIOSocketをNonBlockに設定
ノンブロッキングIO97
ノンブロッキングIO98このサーバーは、無限Loopしながら、接続したクライアントを自分で管理して、通信できる。
99IO多重化
100
101IO多重化
102IO多重化ここでBlock
103IO多重化Select は状態が変化したSocket全てを検知できるので、Blockはしているが、複数のクライアントを処理できる
104例えば... Guzzleのasyncリクエスト
105Guzzleのpromise
106Guzzleのpromise内部では curlmulti が使われていて、poll でIO多重化されてる
107非同期処理では、システムコールやIOモデルの理解が重要になる
108小ネタ3雑に strace を使うと、裏側で使っているシステムコールが簡単に見れる
1. 用語の定義2. なぜ必要なのか?3. 非同期関連の実装4. PHPで使える解決策目次109
110非同期フレームワーク
111Swoole, React, AmPHP
1123者ともに、ノンブロッキングのイベント駆動を指向-> 解決しようとする課題は同じAmp は V3 で Fiber に対応している
113Generator
114Generator (非対称コルーチンの非同期処理実装例 )Ngyuki chatの例 https://qiita.com/ngyuki/items/1f0ec69db9d78ba50ebb
115Fiber
116https://wiki.php.net/rfc/fibersRFC
117https://qiita.com/rana_kualu/items/6247441f6fdd63c10a06【PHP8.1】PHPで簡単に非同期処理を書けるようになる
118とまあ建前は置いておいて
119● 一般開発者が使う機能ではない● コアに入ったのでXdebugが動く● Schedulerとかはまだ● Async/Await とかもまだ
120Generatorと何が違う?
121● スタックのどこからでも停止・再開● FiberError, FiberExit
122じゃあ、今の状態で何ができる?
123Generator同様に、メソッドの実行停止・再開ができる
124Generator同様に、メソッドの実行停止・再開ができるFiberインスタンス生成
125Generator同様に、メソッドの実行停止・再開ができるFiber実行開始
126Generator同様に、メソッドの実行停止・再開ができるここで止まる
127Generator同様に、メソッドの実行停止・再開ができるここで再開
Main と Fiber を行ったりきたり128
Main と Fiber を行ったりきたり129これは非同期じゃない。シングルスレッドで同期的に動いている
非同期IOと組み合わせると...130
非同期IOと組み合わせると...131ノンブロッキングやIO多重化を組み合わせることで suspend に意味がでる
Generatorを使った実装のサンプルはまだまだ少ない私と一緒に是非 shadow-php へ...132
133参考資料
134Mastering Swoole PHP - Bruce DouSwoole 作者による解説著作全体の2/3がPHPの処理モデルやIOモデルの説明となっていて、非同期を取り巻く状況を雑観できる。
135並行プログラミング入門 - 高野 祐輝並行処理について、裏側の仕組みから解説してくれる本包括的に書かれていて、とりあえずコレ一冊やるとだいぶ霧が晴れる感じがあります。
136n月刊ラムダノート Vol.1コルーチンについて、歴史から詳しく載っています。これを読んだおかげで、Async/Await や Promiseについても理解が深まりました。
137計算機プログラムの構造と解釈 第2版第五章 Stream直接非同期には関係ないのだけれど、関数に状態を閉じ込めるという考え方が、非対称コルーチンに通じるところがあり、面白いです。
@hanhan1978相談・指摘・その他 下記のTwitterアカウントにどうぞ138