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

PHPでWebサーバーを作って高速化に挑戦する!/php-web-server

 PHPでWebサーバーを作って高速化に挑戦する!/php-web-server

PHPerKaigi 2022 Day2 の LTです。

Ryo Tomidokoro

April 11, 2022
Tweet

More Decks by Ryo Tomidokoro

Other Decks in Technology

Transcript

  1. @hanhan1978
    PHPでWebサーバーを作って高速化に挑
    戦する!
    PHPerKaigi 2022 LT

    View Slide

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

    View Slide

  3. 本日のテーマ
    3

    View Slide

  4. PHP 8.1 でウェブサーバーを作って
    世界一を目指す!
    4

    View Slide

  5. ルール説明
    5

    View Slide

  6. 各言語、実装、ミドルウェアのウェブサーバーは
    / へのアクセスに対して
    {status : “OK”} というレスポンスを返す
    6

    View Slide

  7. 各言語、実装、ミドルウェアのウェブサーバーは
    / へのアクセスに対して
    {status : “OK”} というレスポンスを返す
    7

    View Slide

  8. ベンチマーカーには wrk を使う。
    ベンチマークコマンドは下記
    wrk -t3 -c100 -d30s –latency http://127.0.0.1:8080/
    8

    View Slide

  9. 9
    実測

    View Slide

  10. まずは対戦相手から
    10

    View Slide

  11. 11
    Go

    View Slide

  12. Nginx
    12
    docker run -v default.conf:/etc/nginx/conf.d/default.conf -p 8080:80 --rm nginx

    View Slide

  13. Node.js
    13

    View Slide

  14. 14

    View Slide

  15. top 1 で簡易に負荷状況を見る
    15

    View Slide

  16. top 1 で簡易に負荷状況を見る
    16
    特定のCPUコアに負荷が偏る

    View Slide

  17. top 1 で簡易に負荷状況を見る
    17

    View Slide

  18. top 1 で簡易に負荷状況を見る
    18
    満遍なく負荷をかけられている
    こちらが理想的な形

    View Slide

  19. 19
    PHP実装

    View Slide

  20. Webサーバーとは?
    ようするに HTTP の仕様にそった
    文字列を Socket 通信で返却すればOK
    20

    View Slide

  21. まずは、シングルプロセス
    21

    View Slide

  22. まずは、シングルプロセス
    22
    実に単純明快

    View Slide

  23. 23
    結果

    View Slide

  24. 無念の敗退
    24

    View Slide

  25. 次は、IO多重化
    25

    View Slide

  26. 次は、IO多重化
    26
    複数コネクションを同時に扱
    えるようになった

    View Slide

  27. 27
    結果

    View Slide

  28. むしろ遅くなる
    28

    View Slide

  29. シンプルすぎる返却値なので
    socket_select 分遅くなったと推測
    29

    View Slide

  30. よし!ノンブロックだ!
    30

    View Slide

  31. よし!ノンブロックだ!
    31
    時代はノンブロッキング

    View Slide

  32. 32
    結果

    View Slide

  33. ブロッキングとほぼ変わらない
    33

    View Slide

  34. この辺で、PHPのコア側にブロックしてい
    る箇所があるという想像が働く
    34

    View Slide

  35. 実際の負荷状況
    35

    View Slide

  36. 実際の負荷状況
    36
    全てのコアが遊びまくっている

    View Slide

  37. ノンブロッキングの場合は無限ループのコードにな
    るので、若干1コアの負荷が上がるが、ほぼ負荷を
    かけられない
    37

    View Slide

  38. 諦めずにpreforkしてみる
    38

    View Slide

  39. 諦めずにpreforkしてみる
    39
    ノンブロッキングサーバーを
    複数プロセスで利用

    View Slide

  40. 40
    結果

    View Slide

  41. ちょっと改善したが...
    41

    View Slide

  42. そろそろ勝てる気がしなくなってきたので
    手当たりしだいに試した
    42

    View Slide

  43. 手当たり次第の結果
    43
    実装 Req/Seq
    Amp 11933
    RoadRunner 19618
    Revolt 20297
    mod-php 30389

    View Slide

  44. なんとか Node.js をかわした
    44

    View Slide

  45. しかし、それでいいのか?
    45

    View Slide

  46. mod-php での実装
    46

    View Slide

  47. mod-php での実装
    47
    これでいいのか?

    View Slide

  48. 助けて Open Swoole …..
    48

    View Slide

  49. Open Swoole での実装
    49

    View Slide

  50. 50
    結果

    View Slide

  51. 勝てば官軍
    51

    View Slide

  52. 52
    優勝だ!

    View Slide

  53. ちょっとだけ、まじめなラップアップ
    53

    View Slide

  54. Open Swoole は、PHPコアのブロッキングする関
    数を独自実装で置き換えている。
    結局のところ、ボトルネックを自前で差し替えるよう
    な豪腕を発揮しない限りPHP単体では勝てないの
    かもしれない。
    54

    View Slide

  55. この件については、まじめな追加調査をします!
    影PHP勉強会でお会いしましょう!
    55

    View Slide