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

PHPで書いて覚える非同期処理 / php-async-programming

PHPで書いて覚える非同期処理 / php-async-programming

これを読んでも、非同期処理はわかりませんが、暗いトンネルの先に光が見えます。

Ryo Tomidokoro

October 03, 2021
Tweet

More Decks by Ryo Tomidokoro

Other Decks in Technology

Transcript

  1. @hanhan1978
    PHPで
    書いて覚える非同期処理
    PHPカンファレンス 2021

    View full-size slide

  2. @hanhan1978
    ● 富所 亮
    ● 所属
    ○ 株式会社カオナビ
    ● 職業
    ○ Webアプリケーションエンジニア
    ● ブログ
    ○ https://blog.hanhans.net
    ● Yokohama North AM
    ○ https://anchor.fm/yokohama-north-am
    2

    View full-size slide

  3. はじめに
    3

    View full-size slide

  4. 4
    PHPアプリケーションは
    同期的なBlocking IOが基本

    View full-size slide

  5. 5
    私達が書いたプログラムは書いた順番に
    処理されて動作する
    人間の脳にとてもやさしい

    View full-size slide

  6. 6
    非同期は、分かりにくい
    界隈では、関連情報が増加してきているのは感じる
    Swoole, React, AmPHP…. Generator, Fiber

    View full-size slide

  7. 7
    書いたプログラムは書いた順番に動くとは
    限らない
    人間の脳にとても厳しい

    View full-size slide

  8. 8
    今回のテーマ

    View full-size slide

  9. 9
    「非同期が分からない!」
    を分解

    View full-size slide

  10. 10
    今日のテーマ

    View full-size slide

  11. 11
    裏テーマ

    View full-size slide

  12. 12
    システムコールとか、Socket通信とかを
    PHPで書こうと思う人を増やす

    View full-size slide

  13. 13
    Webサーバーが作れるようになるぞ!
    https://speakerdeck.com/hanhan1978/phpdewebsabazuo-rou

    View full-size slide

  14. PHPでPHPを動かす時代が来る!
    14
    多分

    View full-size slide

  15. 小ネタ
    平行じゃない => 並行
    平行 : parallel
    並行 : concurrent, (parallel)
    並列 : parallel
    15

    View full-size slide

  16. 1. 用語の定義
    2. なぜ必要なのか?
    3. 非同期関連の実装
    4. PHPで使える解決策
    目次
    16

    View full-size slide

  17. 同期的なプログラミング
    記述したとおりの順番で動作するようなプログラミングモデル
    非同期プログラミング
    独立して発生するイベントに対する処理を記述するための並行プログラミン
    グ手法の総称
    17
    高野祐輝. (2021). 並行プログラミング入門 5章 (初版.). オライリー・ジャパン.

    View full-size slide

  18. 同期的なプログラミング
    記述したとおりの順番で動作するようなプログラミングモデル
    非同期プログラミング
    独立して発生するイベントに対する処理を記述するための並行プログラミン
    グ手法の総称
    18
    高野祐輝. (2021). 並行プログラミング入門 5章 (初版.). オライリー・ジャパン.
    処理の順番はイベントの発
    生順に依存する

    View full-size slide

  19. 19
    Async Programming - ColdBox HMVC Documentation
    https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming

    View full-size slide

  20. 20
    Async Programming - ColdBox HMVC Documentation
    https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming
    タスクは直列に実行され
    るため、全ての処理を足
    し合わせた実行時間にな

    View full-size slide

  21. 21
    Async Programming - ColdBox HMVC Documentation
    https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming
    タスクは並列に実行され
    るため、全体の処理時間
    ≒ 最も長いタスクの時間

    View full-size slide

  22. 22
    例えばPHP

    View full-size slide

  23. 23
    ToDoリストを検索するバックエンドの処理(例)

    View full-size slide

  24. 24
    ToDoリストを検索するバックエンドの処理(例)
    直列に処理しなければ、整合
    性が取れない。
    同期的処理に意味がある

    View full-size slide

  25. 25
    例えばJavaScript

    View full-size slide

  26. 26
    buttonクリックで発生するイベント

    View full-size slide

  27. 27
    buttonクリックで発生するイベント
    ボタンがいつ押されるかは分
    からない。
    非同期的処理に意味がある

    View full-size slide

  28. 28
    例えばJavaScript - part2

    View full-size slide

  29. 29
    ページ読込み後にAjaxでAPIをコールする例

    View full-size slide

  30. 30
    buttonクリックで発生するイベント
    付帯情報は、あとでページに表示
    されれば問題ない
    非同期的処理に意味がある

    View full-size slide

  31. 改めて比べてみると
    向き・不向きに合わせてプログラミングモ
    デルが選択されているだけ
    31
    特にJavaScriptは、処理をブロックしないことに心血を注いでいる

    View full-size slide

  32. 32
    小ネタ2
    JSの人たち
    「たまには同期してほしい」
    PHPの人たち
    「たまには非同期してほしい」

    View full-size slide

  33. 1. 用語の定義
    2. なぜ必要なのか?
    3. 非同期関連の実装
    4. PHPで使える解決策
    目次
    33

    View full-size slide

  34. 34
    JavaScriptで考えてみる

    View full-size slide

  35. 35
    Amazon トップページ

    View full-size slide

  36. 36
    Amazon トップページ
    各要素は、スクロールに合わ
    せて読み込まれる
    非同期であることがUX向上に
    ダイレクトにつながる

    View full-size slide

  37. JSの非同期処理の実行モデル
    37
    https://zenn.dev/qnighy/articles/345aa9cae02d9d

    View full-size slide

  38. 38
    PHP(バックエンド)で考えてみる

    View full-size slide

  39. 39
    いわゆるMVCフレームワーク

    View full-size slide

  40. 40
    いわゆるMVCフレームワーク
    1. 認証して

    View full-size slide

  41. 41
    いわゆるMVCフレームワーク
    2. 過去の参加イベントを
    取る

    View full-size slide

  42. 42
    いわゆるMVCフレームワーク
    3. メインに表示する情報
    を取得

    View full-size slide

  43. 43
    非同期にしてしまうと、事前に必要なデー
    タが取れていない。
    同期的であることに意味があるパターン
    が多い。

    View full-size slide

  44. 44
    バックエンドのひとつのエンドポイントから
    考えると、非同期処理の必要性が分から
    なくなる

    View full-size slide

  45. 45
    うまく適用できた例

    View full-size slide

  46. 46
    https://speakerdeck.com/suzuki/guzzle-promisewoshi-tuta-fei-tong-qi-chu-li-niy
    oruapikorufalsegao-su-hua

    View full-size slide

  47. 47
    https://www.slideshare.net/techblogyahoo/phpioyield-phpcon2014

    View full-size slide

  48. 48
    同時に実行しても問題ないIO処理を束ね

    View full-size slide

  49. 49
    その他の適用例

    View full-size slide

  50. 51
    Laravel Queues [ Pocket Guide ] - DEV Community
    https://dev.to/mvpopuk/laravel-queues-pocket-guide-c6a

    View full-size slide

  51. 52
    イベント監視が別プロセスだけど...
    メール送信、退会バッチ処理等、適用範囲も広
    い。長いIOを他のプロセスにまかせてしまい結
    果をすばやく戻す

    View full-size slide

  52. 53
    PHP単体だと、非同期処理は適用範囲が
    狭い

    View full-size slide

  53. 54
    なぜ非同期フレームワークは生まれ
    なぜFiberは実装されるのか

    View full-size slide

  54. 55
    視野を広げてみる必要がある

    View full-size slide

  55. 56
    いわゆる PHP のWebアプリ

    View full-size slide

  56. 57
    Nginx + PHP-FPM
    PHP処理系の気の効いた図

    View full-size slide

  57. 1リクエストに対して 1つのPHP実行プロセス
    58

    View full-size slide

  58. 1リクエストに対して 1つのPHP実行プロセス
    59
    各リクエストは、隔離されたプロセ
    スで実行され、互いに影響しない

    View full-size slide

  59. 60
    既存のPHPの処理モデルは
    同期的、ステートレス

    View full-size slide

  60. 61
    例えば、Swoole PHP

    View full-size slide

  61. Swooleサーバーの概要図
    62

    View full-size slide

  62. Swooleプロセス自体が1つのPHPプロセス
    63

    View full-size slide

  63. Swooleプロセス自体が1つのPHPプロセス
    64
    各リクエストは、同じプロセス内で
    実行される。
    コルーチンで分離されている

    View full-size slide

  64. 65
    Swoole が非同期で目指すこと
    1つのコルーチンがIO処理待ちになったら、次のコ
    ルーチンに処理を移す
    CPUの利用効率をあげる。

    View full-size slide

  65. 66
    Swoole が目指すのは
    非同期的でステートフルな処理モデル

    View full-size slide

  66. 67
    しかし、エンドポイント単位の視点に立つ

    -> リクエストは同期的に処理されているよ
    うにみえる

    View full-size slide

  67. 68
    だから、PHPerには非同期処理がわかり
    ずらい。

    View full-size slide

  68. 1. 用語の定義
    2. なぜ必要なのか?
    3. 非同期関連の実装
    4. PHPで使える解決策
    目次
    69

    View full-size slide

  69. この章はPHPで非同期実装の感覚を養う話
    70

    View full-size slide

  70. 71
    PHP単体での非同期処理の仕組みはな
    い(多分)
    システムコールと組み合わせて、非同期
    に処理を行う実装を行う

    View full-size slide

  71. 72
    ここで、ちょっとだけ事前説明

    View full-size slide

  72. 73
    システムコール
    オペレーティングシステム (OS)(より明確に言えばOS
    のカーネル)の機能を呼び出すために使用される機構
    のこと。

    View full-size slide

  73. 74
    Socket Functions
    https://www.php.net/manual/en/ref.sockets.php

    View full-size slide

  74. 75
    Socket通信

    View full-size slide

  75. 76
    https://world4java.wordpress.com/2014/02/28/socket-programming/
    Socket Programming

    View full-size slide

  76. 77
    IOモデル

    View full-size slide

  77. 78
    ● ブロッキング IO
    ● ノンブロッキング IO
    ● IO 多重化
    ● シグナル IO
    ● 非同期 IO

    View full-size slide

  78. 79
    ● ブロッキング IO
    ● ノンブロッキング IO
    ● IO 多重化
    ● シグナル IO
    ● 非同期 IO ← この2つは今日は扱いません

    View full-size slide

  79. 80
    IOモデルを文章だけで
    理解するのは難しいので...

    View full-size slide

  80. 81
    Echoサーバー

    View full-size slide

  81. 82
    文字列を受け取って、文字列を返すだけのサーバー

    View full-size slide

  82. 83
    文字列を受け取って、文字列を返すだけのサーバー
    echoサーバーに接続

    View full-size slide

  83. 84
    文字列を受け取って、文字列を返すだけのサーバー
    入力した文字列がそのま
    ま戻ってくる

    View full-size slide

  84. 85
    Echoサーバー実装は、非同期処理関連の実
    装技術を知るための、極めて効果的でコスパ
    が高い方法
    写経をオススメします!!

    View full-size slide

  85. 86
    https://speakerdeck.com/bati11/otozhong-liang-kunaruhua
    C言語の実装例
    本当はコレを写経するのが良い
    が...

    View full-size slide

  86. PHPでの実装例
    87
    https://github.com/hanhan1978/shadow-php/tree/master/echo-server

    View full-size slide

  87. 88
    Blocking IO

    View full-size slide

  88. 90
    ブロッキングIO

    View full-size slide

  89. 91
    ブロッキングIO
    SocketでListen

    View full-size slide

  90. 92
    ブロッキングIO
    ここでBlock

    View full-size slide

  91. 93
    ブロッキングIO
    このサーバーは、通信をBlockするの
    で、一度に1クライアントしか扱えない

    View full-size slide

  92. 94
    NonBlocking IO

    View full-size slide

  93. 96
    ノンブロッキングIO
    SocketをNonBlockに設定

    View full-size slide

  94. ノンブロッキングIO
    97

    View full-size slide

  95. ノンブロッキングIO
    98
    このサーバーは、無限Loopしなが
    ら、接続したクライアントを自分で管
    理して、通信できる。

    View full-size slide

  96. 99
    IO多重化

    View full-size slide

  97. 101
    IO多重化

    View full-size slide

  98. 102
    IO多重化
    ここでBlock

    View full-size slide

  99. 103
    IO多重化
    Select は状態が変化したSocket全
    てを検知できるので、Blockはしてい
    るが、複数のクライアントを処理でき

    View full-size slide

  100. 104
    例えば... Guzzleのasyncリクエスト

    View full-size slide

  101. 105
    Guzzleのpromise

    View full-size slide

  102. 106
    Guzzleのpromise
    内部では curlmulti が使われて
    いて、poll でIO多重化されてる

    View full-size slide

  103. 107
    非同期処理では、システムコールやIOモ
    デルの理解が重要になる

    View full-size slide

  104. 108
    小ネタ3
    雑に strace を使うと、裏側で使っている
    システムコールが簡単に見れる

    View full-size slide

  105. 1. 用語の定義
    2. なぜ必要なのか?
    3. 非同期関連の実装
    4. PHPで使える解決策
    目次
    109

    View full-size slide

  106. 110
    非同期フレームワーク

    View full-size slide

  107. 111
    Swoole, React, AmPHP

    View full-size slide

  108. 112
    3者ともに、ノンブロッキングのイベント駆
    動を指向
    -> 解決しようとする課題は同じ
    Amp は V3 で Fiber に対応している

    View full-size slide

  109. 113
    Generator

    View full-size slide

  110. 114
    Generator (非対称コルーチンの非同期処理実装例 )
    Ngyuki chatの例 https://qiita.com/ngyuki/items/1f0ec69db9d78ba50ebb

    View full-size slide

  111. 116
    https://wiki.php.net/rfc/fibers
    RFC

    View full-size slide

  112. 117
    https://qiita.com/rana_kualu/items/6247441f6fdd63c10a06
    【PHP8.1】PHPで簡単に非同期処理を書けるようになる

    View full-size slide

  113. 118
    とまあ建前は置いておいて

    View full-size slide

  114. 119
    ● 一般開発者が使う機能ではない
    ● コアに入ったのでXdebugが動く
    ● Schedulerとかはまだ
    ● Async/Await とかもまだ

    View full-size slide

  115. 120
    Generatorと何が違う?

    View full-size slide

  116. 121
    ● スタックのどこからでも停止・再開
    ● FiberError, FiberExit

    View full-size slide

  117. 122
    じゃあ、今の状態で何ができる?

    View full-size slide

  118. 123
    Generator同様に、メソッドの実行停止・再開ができる

    View full-size slide

  119. 124
    Generator同様に、メソッドの実行停止・再開ができる
    Fiberインスタンス生成

    View full-size slide

  120. 125
    Generator同様に、メソッドの実行停止・再開ができる
    Fiber実行開始

    View full-size slide

  121. 126
    Generator同様に、メソッドの実行停止・再開ができる
    ここで止まる

    View full-size slide

  122. 127
    Generator同様に、メソッドの実行停止・再開ができる
    ここで再開

    View full-size slide

  123. Main と Fiber を行ったりきたり
    128

    View full-size slide

  124. Main と Fiber を行ったりきたり
    129
    これは非同期じゃない。シングル
    スレッドで同期的に動いている

    View full-size slide

  125. 非同期IOと組み合わせると...
    130

    View full-size slide

  126. 非同期IOと組み合わせると...
    131
    ノンブロッキングやIO多重化を組
    み合わせることで suspend に意
    味がでる

    View full-size slide

  127. Generatorを使った実装のサンプルはま
    だまだ少ない
    私と一緒に是非 shadow-php へ...
    132

    View full-size slide

  128. 133
    参考資料

    View full-size slide

  129. 134
    Mastering Swoole PHP - Bruce Dou
    Swoole 作者による解説著作
    全体の2/3がPHPの処理モデル
    やIOモデルの説明となっていて、
    非同期を取り巻く状況を雑観でき
    る。

    View full-size slide

  130. 135
    並行プログラミング入門 - 高野 祐輝
    並行処理について、裏側の仕組
    みから解説してくれる本
    包括的に書かれていて、とりあえ
    ずコレ一冊やるとだいぶ霧が晴れ
    る感じがあります。

    View full-size slide

  131. 136
    n月刊ラムダノート Vol.1
    コルーチンについて、歴史から詳
    しく載っています。
    これを読んだおかげで、
    Async/Await や Promiseについ
    ても理解が深まりました。

    View full-size slide

  132. 137
    計算機プログラムの構造と解釈 第2版
    第五章 Stream
    直接非同期には関係ないのだけ
    れど、関数に状態を閉じ込めると
    いう考え方が、非対称コルーチン
    に通じるところがあり、面白いで
    す。

    View full-size slide

  133. @hanhan1978
    相談・指摘・その他 
    下記のTwitterアカウントにどうぞ
    138

    View full-size slide