Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

@hanhan1978 ● 富所 亮 ● 所属 株式会社カオナビ💎 Expert ● 職業 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

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

Slide 5

Slide 5 text

ルール説明 5

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

9 実測

Slide 10

Slide 10 text

まずは対戦相手から 10

Slide 11

Slide 11 text

11 Go

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Node.js 13

Slide 14

Slide 14 text

14

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

19 PHP実装

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

23 結果

Slide 24

Slide 24 text

無念の敗退 24

Slide 25

Slide 25 text

次は、IO多重化 25

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

27 結果

Slide 28

Slide 28 text

むしろ遅くなる 28

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

32 結果

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

実際の負荷状況 35

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

諦めずにpreforkしてみる 38

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

40 結果

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

mod-php での実装 46

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

助けて Open Swoole ….. 48

Slide 49

Slide 49 text

Open Swoole での実装 49

Slide 50

Slide 50 text

50 結果

Slide 51

Slide 51 text

勝てば官軍 51

Slide 52

Slide 52 text

52 優勝だ!

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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