Slide 1

Slide 1 text

Laravel JP Conference PHPでもgRPCサーバを立てたいだけの人生だった 2019年2月16日 (土) 株式会社Nextat 中榮健二 Nextat Inc. 1

Slide 2

Slide 2 text

1月某日 カンファレンスのタイムテーブルを見たぼく「???」 Nextat Inc. 2

Slide 3

Slide 3 text

実質LT枠だこれ! 紅白の裏番組みたいなセッションへようこそ! Nextat Inc. 3

Slide 4

Slide 4 text

自己紹介 京都から来ました ‒ 中榮健二 (なかえけんじ) ‒ twitter: @n̲1215  ‒ 株式会社Nextat 取締役 ‒ baserCMS コアコミッター ‒ 普段は Laravel + Unity でソシャゲ開発など ‒ 好きなIlluminateコンポーネントはilluminate/container Nextat Inc. 4

Slide 5

Slide 5 text

発表概要 1. gRPCとは 2. Protocol Buffers 3. gRPCの使いどころ 4. PHPとgRPC 5. PHPでgRPCサーバを実現する試み 6. gRPCサーバに見るPHPの未来 Nextat Inc. 5

Slide 6

Slide 6 text

今日のお題はLaravelにほぼ関係ない話ですが ぼくはLaravelにつよいエンジニアなので Laravelの話も申し訳程度に挟んでいきます Nextat Inc. 6

Slide 7

Slide 7 text

1. gRPCとは Nextat Inc. 7

Slide 8

Slide 8 text

gRPCとは Google製のRPCフレームワーク → gpc.io RPC = Remote Procedure Call (遠隔手続呼出) 'g' の意味はリリース毎に違うらしい 1.0 'g' stands for 'gRPC', 1.1 'g' stands for 'good', ... Microservicesの文脈でサービス間通信での利用例が増えている ハイパフォーマンス Nextat Inc. 8

Slide 9

Slide 9 text

gRPCの通信プロトコル over HTTP/2を前提に策定されている メッセージのボディがバイナリ TCPコネクションの使い回し ネットワークリソース利用効率 最近gRPC‒Webという追加の仕様/ライブラリがGAに gRPCのための機能が足りないWebブラウザにも対応 Nextat Inc. 9

Slide 10

Slide 10 text

サーバ・クライアント間の通信の種類 4種類 HTTP/2だから効率よく双方向通信が可能 Nextat Inc. 10

Slide 11

Slide 11 text

(1) Unary RPCs 1リクエスト / 1レスポンス 多くのWebアプリ開発者が慣れ親しんだもの Nextat Inc. 11

Slide 12

Slide 12 text

(2) Server streaming RPCs 1リクエストに対しサーバが複数回のレスポンスを返す 送信完了までクライアントがストリームからメッセージを読む サーバープッシュ Nextat Inc. 12

Slide 13

Slide 13 text

(3) Client streaming RPCs 複数回のリクエストを送信しサーバが1回レスポンスを返す 送信完了までサーバがストリームからメッセージを読む データのアップロードなどに利用可能 Nextat Inc. 13

Slide 14

Slide 14 text

(4) Bidirectional streaming RPCs リクエストとレスポンスが多対多 双方向ストリーミング 順序に決まりはない チャットなどに利用可能 Nextat Inc. 14

Slide 15

Slide 15 text

2. Protocol Buffers Nextat Inc. 15

Slide 16

Slide 16 text

Protocol Buffers (Protobuf) gRPCが利用するIDL 兼 メッセージ交換用のバイナリフォーマット IDL = Interface Definition Language インタフェース記述言語 プログラミング言語に依存しない .protoファイルから言語実装を自動生成できる gRPCとは独立して使うこともできる 例)REST API + リクエストボディやレスポンスボディに Protocol Buffers Nextat Inc. 16

Slide 17

Slide 17 text

Protocol Buffers 定義ファイル の書式 Message → リクエストやレスポンスのデータ構造を記述 Service → RPCの定義を記述 // service.proto syntax = "proto3"; package service; service Echo { rpc Ping (Message) returns (Message) { } } message Message { string msg = 1; } Nextat Inc. 17

Slide 18

Slide 18 text

protoc (Protocol Compiler) .protoファイルをprotocでビルドして各言語の実装を生成する 拡張が容易 $ protoc -I=. --php_output=. service.proto Nextat Inc. 18

Slide 19

Slide 19 text

3. gRPCの使いどころ Nextat Inc. 19

Slide 20

Slide 20 text

gRPCのメリット パフォーマンス、ネットワークリソースの効率的利用 双方向通信 クライアントの実装が言語ごとに自動生成できる スキーマが定まるので型のエラーが起きにくい コンパイル時のエラーないし静的解析で検知しやすい 定義ファイルの内容がそのままAPIの定義となる 実装とAPIドキュメントが剥離しない JSON Schema / Open API / Swagger etc. からの解放! Nextat Inc. 20

Slide 21

Slide 21 text

gRPCのデメリット 開発中に通信の中身を確認しにくい HTTP/2は実質暗号化通信が必須 バイナリフォーマット grpc‒gateway(gRPC to JSON proxy)などの周辺ツール 定義ファイルから各言語の実装をビルドするのが少し手間 サーバとクライアントで定義ファイルのバージョンが違って落ちるこ とも v3でクライアントが壊れにくいように改善している Nextat Inc. 21

Slide 22

Slide 22 text

gRPCの使いどころ マイクロサービスのバックエンドでのサービス間通信 公式クライアントしかないスマホアプリ用のサーバ ゲームのAPIサーバ チャットやバトルシステムの通信方式をまとめられる gRPCの亜種の例もあり 一般向けの公開APIに用いるのは今のところつらそう ブラウザ対応は今後改善されていくはず Nextat Inc. 22

Slide 23

Slide 23 text

gRPC良さそうじゃん!使ってみたい! Nextat Inc. 23

Slide 24

Slide 24 text

4. PHPとgRPC Nextat Inc. 24

Slide 25

Slide 25 text

ここでPHPerの皆様には 悲しいお知らせがあります Nextat Inc. 25

Slide 26

Slide 26 text

PHPでのgRPCサーバは茨の道です PHP界隈ではgRPCの話はほとんど聞かない phpconでクライアントの話: php grpc‒client in phpcon2018 PHPによるgRPCクライアントは公式サポート リクエスト使い捨てのPHPの通常の動作方式ではStreamingが不可能 ドキュメント(PHP用): サーバ側はNode.JSを使ってね ❤ Google Groupでのとある発言 : PHPでgRPCサーバ作っても特殊な 構成になるしあまり役に立たないよね(意訳) 参考: なぜPHPはgRPCサーバーがサポートされていないのか? Nextat Inc. 26

Slide 27

Slide 27 text

PHPerのぼく涙目 言語に依存しないって言ったじゃない!!!!! Google様謹製の某langに宗旨替えするしかないのか? Nextat Inc. 27

Slide 28

Slide 28 text

PHPは歯ブラシ PHPは◯◯◯である ‒ quipped PHPは歯ブラシくらい興奮に値する。シンプルで、毎日使う便利な道 具。 伝説のPHP作者「Rasmus Lerdorf」名言集を聞くと嫌PHP厨がファ ビョる 歯を磨くための便利な道具 Nextat Inc. 28

Slide 29

Slide 29 text

えらい人が用途にあったプログラム言語 を選べとおっしゃる Nextat Inc. 29

Slide 30

Slide 30 text

あなた達はいつも正しいね…… Nextat Inc. 30

Slide 31

Slide 31 text

だがここは Laravel JP Con ロマン枠(実質LT枠) Nextat Inc. 31

Slide 32

Slide 32 text

PHPerには歯ブラシで船舶を磨く 自由が与えられている ってボクが言ってました Nextat Inc. 32

Slide 33

Slide 33 text

5. PHPでgRPCサーバを実現する試み Nextat Inc. 33

Slide 34

Slide 34 text

PHPだけ仲間はずれは寂しい 公式非サポートに反旗を翻すPHPerたちの姿が PHPのみで実現するわけではない 通常のPHPの構成でダメなら通常じゃない構成でやればいいじゃない Unary RPC対応だけでも嬉しい Nextat Inc. 34

Slide 35

Slide 35 text

5‒1. PHP‒FPM 前段にProxy gRPC → FastCGI 通常の構成から大きくは外れない GitHubでもいくつか見つかるがほとんど更新が止まっている bakins/grpc‒fastcgi‒proxy LTD‒Beget/grpc‒to‒fpm 基本的にUnary RPCのみ。stream対応は辛そう Nextat Inc. 35

Slide 36

Slide 36 text

Nextat Inc. 36

Slide 37

Slide 37 text

5‒2. Swoole https://www.swoole.co.uk/ コルーチンベースの非同期並行実行ライブラリ(PHP拡張/C言語) SwooleのHTTPサーバはHTTP/2にも対応し、ハイパフォーマンス Unary RPCが実装可能であることが示されている gRPCフレームワークとしての整備はされていない Swoole自体は中華圏で実績あり。WeChatのテンセントなど Nextat Inc. 37

Slide 38

Slide 38 text

なぜか公式grpc‒clientのリポジトリに gRPCサーバ実装例 Nextat Inc. 38

Slide 39

Slide 39 text

5‒3. php‒grpc (RoadRunner)   https://github.com/spiral/php‒grpc RoadRunner (Golang製のPHPアプリケーションサーバ) を利用 前面のGoサーバがgRPCのリクエストを受け、PHPのworkerに振る 開発元は Spiral Scout 開発の経緯: PHP was never meant to die 最新のプレゼン資料(ロシア語): RoadRunner Nextat Inc. 39

Slide 40

Slide 40 text

php‒grpcを試した 調べた中で一番コード生成などが整っていそうだった 前述の定義ファイルを // service.proto syntax = "proto3"; package service; service Echo { rpc Ping (Message) returns (Message) { } } message Message { string msg = 1; } Nextat Inc. 40

Slide 41

Slide 41 text

Serviceの実装例 コンパイルするとインターフェースが自動生成されるので実装する setMsg(strtoupper($in->getMsg())); } } Nextat Inc. 41

Slide 42

Slide 42 text

ワーカーのエントリポイントの実装例 RoadRunnerがワーカーを起動するエントリポイントのファイルを作成 registerService( \Service\EchoInterface::class, new \App\EchoService() ); $streamRelay = new \Spiral\Goridge\StreamRelay(STDIN, STDOUT); $worker = new \Spiral\RoadRunner\Worker($streamRelay); $server->serve($worker); Nextat Inc. 42

Slide 43

Slide 43 text

せっかくなのでクライアントもPHPで $credential, ]); $message = new Service\Message(); $message->setMsg(!empty($argv[1]) ? $argv[1] : 'Hello'); [$reply, $status] = $client->Ping($message)->wait(); $client->close(); echo 'Server Response: ' . $reply->getMsg() . PHP_EOL; Nextat Inc. 43

Slide 44

Slide 44 text

サーバ golang製なのでビルドするとワンバイナリになる: rr‒grpc 設定はyamlで手軽に書ける .rr.yaml grpc: listen: "tcp://:9001" proto: "../protos/service.proto" 定義ファイル tls: key: "../cert/server.key" cert: "../cert/server.crt" workers: command: "php worker.php" エントリポイントのファイルを実行 pool: numWorkers: 4 ワーカーの数 Nextat Inc. 44

Slide 45

Slide 45 text

サーバを起動 $ rr-grpc serve -v -d Nextat Inc. 45

Slide 46

Slide 46 text

クライアントを実行 Nextat Inc. 46

Slide 47

Slide 47 text

サーバ側の様子 Nextat Inc. 47

Slide 48

Slide 48 text

PHPで実装を書いたサーバとクライアントでgRPC通信ができた! ストリーミングはまだ試してません SwooleとRoadRunnerはイケそうな感触 Nextat Inc. 48

Slide 49

Slide 49 text

6. gRPCサーバに見るPHPの未来 Nextat Inc. 49

Slide 50

Slide 50 text

PHPアプリケーションサーバの新潮流 Swoole、PHP PM、RoadRunner etc. gRPCのためだけに作られたわけではない 非同期・並行処理やハイパフォーマンスのため アプリケーションサーバの柔軟性のため よりPHPに近いところもしくはPHP自体でサーバを制御したい alt PHP‒FPM Nextat Inc. 50

Slide 51

Slide 51 text

従来のPHPのメリット: リクエストごとに状態がリセットされる 不正な状態が後に残りにくい 状態に無頓着なコードでも比較的安全 Nextat Inc. 51

Slide 52

Slide 52 text

デメリット リクエストごとに初期化処理 パフォーマンスが犠牲に PHP自体はとても速くなったにも関わらず リクエスト毎に同じ処理をしていては遅い フルスタックなLaravelは顕著に重い 色々なキャッシュで高速化 Nextat Inc. 52

Slide 53

Slide 53 text

alt PHP‒FPMによるトレードオフの反転 PHPアプリケーションの初期化処理を前倒しできるものが多い サーバorワーカーの立ち上げ時に初期化 リクエストごとの重複処理がなくなる Appサーバ起動時の初期化は他言語では普通にやっていること キャッシュしたらリクエストをまたいで状態が残るのは同じでしょ? Nextat Inc. 53

Slide 54

Slide 54 text

PHP最大のメリットを捨てて "速さ"を手に入れる Nextat Inc. 54

Slide 55

Slide 55 text

参考: Swooleのベンチマーク TechEmpower Framework Benchmarksより PHP7 Laravel Nextat Inc. 55

Slide 56

Slide 56 text

Swoole 多言語の強豪たちを押しのけ4位 PHPというかC Nextat Inc. 56

Slide 57

Slide 57 text

今からできること PHPでgRPCサーバを実戦投入するのは時期尚早 安定して流行すると仮定しても数年はかかる 今からPHPの変化に備えることはできる Nextat Inc. 57

Slide 58

Slide 58 text

今からできること ~ HTTP FastCGIよりHTTPの世界に近くなる HTTPやTLSの勉強 HTTP/2全然わからん。え、もうHTTP/3が? HTTPメッセージのライブラリへの習熟 PSR‒7が選ばれることが予想される。実装はいくつかある LaravelはSymfony HTTP Foundationを採用しているが PSR‒7 Bridgeはある Nextat Inc. 58

Slide 59

Slide 59 text

今からできること ~ 疎結合な設計 フレームワークとユーザコードの分離 複数の構成を考慮したフレームワークがどんどん出てきそう いざという時に移し替えられるように プレゼンテーション層の分離 サクッとHTTPメッセージの中身を変更できるように Nextat Inc. 59

Slide 60

Slide 60 text

今からできること ~ 初期化処理と状態 イミュータビリティを意識 完全コンストラクタ サービスコンテナによる依存解決に気をつける HTTPリクエスト依存のクラスをコンテナに入れない バグの温床になる LaravelのFormRequestの設計はこの文脈ではアンチパターン HTTPリクエストから導出される値や認証済ユーザなども同様 個別のHTTPリクエストを受ける前に解決できる処理なのかどうか キャッシュやパフォーマンスを考えることにも繋がる Nextat Inc. 60

Slide 61

Slide 61 text

まとめ gRPCとProtocol Buffersはいいぞ PHPのgRPCサーバは公式サポートがない が、PHP界隈でもgRPCサーバに対応する動きがある Swoole、RoadRunnerなど脱PHP‒FPMの流れ PHPの今後に期待 Nextat Inc. 61

Slide 62

Slide 62 text

追伸 RoadRunnerを触っていたらビルドの都合でgolang不可避 入信した 1.11で入ったModulesが便利 Nextat Inc. 62

Slide 63

Slide 63 text

ご清聴ありがとうございました この後のAsk The Speakerでも質問受付 お手柔らかに We're hiring!! Nextat Inc. 63