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