PHPerKaigi 2022 Day2 の LTです。
@hanhan1978PHPでWebサーバーを作って高速化に挑戦する!PHPerKaigi 2022 LT
View Slide
@hanhan1978● 富所 亮● 所属株式会社カオナビ💎 Expert● 職業Webアプリケーションエンジニア● ブログhttps://blog.hanhans.net● Yokohama North AMhttps://anchor.fm/yokohama-north-am2
本日のテーマ3
PHP 8.1 でウェブサーバーを作って世界一を目指す!4
ルール説明5
各言語、実装、ミドルウェアのウェブサーバーは/ へのアクセスに対して{status : “OK”} というレスポンスを返す6
各言語、実装、ミドルウェアのウェブサーバーは/ へのアクセスに対して{status : “OK”} というレスポンスを返す7
ベンチマーカーには wrk を使う。ベンチマークコマンドは下記wrk -t3 -c100 -d30s –latency http://127.0.0.1:8080/8
9実測
まずは対戦相手から10
11Go
Nginx12docker run -v default.conf:/etc/nginx/conf.d/default.conf -p 8080:80 --rm nginx
Node.js13
14
top 1 で簡易に負荷状況を見る15
top 1 で簡易に負荷状況を見る16特定のCPUコアに負荷が偏る
top 1 で簡易に負荷状況を見る17
top 1 で簡易に負荷状況を見る18満遍なく負荷をかけられているこちらが理想的な形
19PHP実装
Webサーバーとは?ようするに HTTP の仕様にそった文字列を Socket 通信で返却すればOK20
まずは、シングルプロセス21
まずは、シングルプロセス22実に単純明快
23結果
無念の敗退24
次は、IO多重化25
次は、IO多重化26複数コネクションを同時に扱えるようになった
27結果
むしろ遅くなる28
シンプルすぎる返却値なのでsocket_select 分遅くなったと推測29
よし!ノンブロックだ!30
よし!ノンブロックだ!31時代はノンブロッキング
32結果
ブロッキングとほぼ変わらない33
この辺で、PHPのコア側にブロックしている箇所があるという想像が働く34
実際の負荷状況35
実際の負荷状況36全てのコアが遊びまくっている
ノンブロッキングの場合は無限ループのコードになるので、若干1コアの負荷が上がるが、ほぼ負荷をかけられない37
諦めずにpreforkしてみる38
諦めずにpreforkしてみる39ノンブロッキングサーバーを複数プロセスで利用
40結果
ちょっと改善したが...41
そろそろ勝てる気がしなくなってきたので手当たりしだいに試した42
手当たり次第の結果43実装 Req/SeqAmp 11933RoadRunner 19618Revolt 20297mod-php 30389
なんとか Node.js をかわした44
しかし、それでいいのか?45
mod-php での実装46
mod-php での実装47これでいいのか?
助けて Open Swoole …..48
Open Swoole での実装49
50結果
勝てば官軍51
52優勝だ!
ちょっとだけ、まじめなラップアップ53
Open Swoole は、PHPコアのブロッキングする関数を独自実装で置き換えている。結局のところ、ボトルネックを自前で差し替えるような豪腕を発揮しない限りPHP単体では勝てないのかもしれない。54
この件については、まじめな追加調査をします!影PHP勉強会でお会いしましょう!55