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

サーバーとは何かを理解して、コンテナ1つで実行しよう | PHPerKaigi2024

サーバーとは何かを理解して、コンテナ1つで実行しよう | PHPerKaigi2024

sadnessOjisan

March 07, 2024
Tweet

More Decks by sadnessOjisan

Other Decks in Technology

Transcript

  1. 22

  2. • Git 入れます • Vim 入れます • npm 入れます •

    apt-get します • docker-php-ext-installします • pecl installします 31
  3. • Git 入れます • Vim 入れます • npm 入れます •

    apt-get します • docker-php-ext-installします • pecl installします ฅ(´・ω・`)ฅ (ここに huh-cat の画像) 32
  4. • Git 入れます • Vim 入れます • npm 入れます •

    apt-get します • docker-php-ext-installします • pecl installします • Apache 入れます • Nginx入れます 34
  5. ฅ(´・ω・`)ฅ (ここに huh-cat の画像) ฅ(´・ω・`)ฅ (ここに huh-cat の画像) ฅ(´・ω・`)ฅ (ここに

    huh-cat の画像) • Git 入れます • Vim 入れます • npm 入れます • apt-get します • docker-php-ext-installします • pecl installします • Apache 入れます • Nginx入れます 35
  6. 高速なビルド • Docker のコマンド一つ一つがレイヤーになっ ていて、コンテナはレイヤーの積み重ね • レイヤーに変更がなければキャッシュが 使える • COPYの順番、マルチステージドビルドが鍵

    src にしか変更が入っていなくても、 COPY のレイヤーに差分が生まれているの で、毎回 yarn install してしまう src にしか変更が入っていないなら、 yarn install まではキャッシュが効く 43
  7. PHPで実現できる? • 高速なビルド ◦ 😄 composer の lock を COPY

    すればできそう • 小さいイメージ ◦ 😖そもそも distroless が存在していない ◦ 😖PHPのサーバーを単体で実行することが難しいので Webサーバー同梱になりそう • 役割を小さく ◦ 😖設計によっては Win/Mac で同じ様に動かすのが難しく、チーム開発はコンテナを開発環境に 使った方が安定しそう 46
  8. パソコンの中のプロセスとスレッド • アクティビティモニタから見れる • プロセスもスレッドもアプリケーション やプログラムの処理の単位 • プロセス: アプリケーションやプログラ ムそのもの

    • スレッド: プロセスを構成する処理の単 位 • 注: 具体例から導いただけで正しい説明ではないです。環境依存でも あるので正しい説明をするのはここでは控えます 54
  9. プロセス間通信は可能なのか • プロセス間は分離されているのでできなさそう • 例: Discord から Notion のデータにアクセスできない •

    ただし、Finder の画像をChromeで添付などはできるわけで、プロセスを跨いで データをやりとりする口はありそう • ファイルディスクリプターを介す 55
  10. HTTPからアプリケーションロジックへ 1. ソケット経由で read すれば TCP 上の(streamの)テキストを入手できる 2. HTTPでパースできたらヘッダとボディの情報が手に入る 3.

    ヘッダからパスがわかればルーティングできるし、ボディにデータが入っていたら保存 できるなど、その値を元にプログラムの分岐や処理をかける 4. 最後に(streamに) write すればレスポンスを返せる 61
  11. マルチプロセスサーバー • システムコール fork でプ ロセスを複数つくれる • CPUのコア数まで並行に処 理を行える •

    1 リクエストに紐づく処理 を別プロセスに任せるので 順番待ちにならない • リクエスト来てからプロセ ス作ると遅い 66
  12. マルチスレッドサーバー • システムコール clone • 各プログラミング言語にも spawn 的な名前 のメソッドが生えているはず •

    メンタルモデル的にはプロセスと同じ • プロセスと違って、スレッド間はデータを共 有できる(レースコンディションの危険) 71
  13. C10K問題 1req ごとに 1 native thread を割り当てていた ら、クライアントの数が増えれば増えるほど負荷 が高まる ハードウェアの性能的に余裕があっても性能が劣

    化することがあり、それを C10K 問題と呼ぶ C10K 問題は fd, pid の枯渇、スレッドを固定長 サイズで確保することによるメモリの無駄遣い、 コンテキストスイッチコストを含む これを解決する方法が 1req ごとに 1 native thread を割り当てない技術で、シングルスレッ ド+イベントループ+IO 多重化 https://blog.ojisan.io/c10k-wakaran/ 74
  14. シングルスレッド・非同期処理のコンセプト • イベントループによる Reactor Pattern • IO が来たらイベントを発行し、キューに 積む •

    メインループでキューの中身を取り出し て、イベントを実行 • イベントが非同期処理を呼び出したのであ れば、完了後にイベントを発行するように して、待ち時間に別のイベントを実行 https://www.oreilly.co.jp/book s/9784873118734/ 78
  15. ファイルディスクリプターを監視する • IOが来たときに発火 • IOが来たことはファイルディスクリプタの 監視を通して行う • select, poll, epoll

    • epoll がゲームチェンジャー。select, poll は自分からファイルディスクリプタを見に 行く必要があって、数が増えるとオーバー ヘッドになっていたが、epoll は IO 発生の 通知をもらえる設計。大量の IO を捌けるよ うになった。 https://blog.ojisan.io/how-to-epoll/ 79
  16. PHPの実行方法 • Server API(SAPI) を決めて実行する • SAPI ◦ CLI: PHPコマンド

    ◦ CGI: WebServerがHTTPを受けて、CGIプロトコルでPHPプログラムを起動する ◦ FastCGI: 同上、FastCGIプロトコルでPHPプロセスにアクセス ◦ Apache: Webサーバー(Apache)に組み込まれているPHPモジュールを実行 92 (ゝω・)vキャピ
  17. Apache で PHP を実行 • PHPは元々 CGI 集でしかなかったが、PHP2で NCSAサーバー(後のApache)に統合され、その 上で実行できるような仕組みになる

    • なので、PHPの実行の源流とも言える • Apache と同じプロセスで PHP を実行(モジュー ル版)できるし、もちろん fork もできる https://www.oreilly.co.jp/books/9784814400270/ 93
  18. CGI で PHP を実行 • 処理を実行するために別プロセスを立ち上げて実行されるプログラム。Web サーバーから呼び出されることが多い。 • 元々は使い捨てだが、FastCGIは一度立ち上げたプロセスを使いまわすことで効 率化を図る

    • Nginxでリクエストを受けて FastCGI 経由で PHP を実行し、その結果を Nginx が返すという設計がよくされる。このときにFPM(FastCGI Process Manager) が必要になる。 94
  19. PHP とモダンな並行プログラミング • Swoole ◦ 非同期ランタイムを実装。Node.jsと同じモデル • FrankenPHP ◦ PHPを動かすことを想定したWebサーバー。Go実装。

    少なくとも Webサーバー自体は M:N グリーンスレッ ドモデル(net/http と Goroutine への言及があるた め)。SAPI の先の処理系が扱うスレッドモデルは不 明(調べ切れていないです、詳しい人教えて欲しいで す><) 98
  20. 2024年現在、必要なのか? • Docker使っている以上はクラウドネイティブな設計のはず。LBやCDNが前段に いるはず。 • 証明書は?: 前段を TLS 終端にすれば良い •

    静的アセットは?: オブジェクトストレージから配信すればよい、CDNへの beresp で Cache-Control をつければ良い 111