Working with TCP Sockets 読書メモ 第22章 ハイブリッド

Working with TCP Sockets 読書メモ 目次

ハイブリッド

  • 複数のパターンを組み合わせて使うこともできる

nginx

  • Cで実装された高速なWebサーバ
  • メインはPreforkパターン
  • forkされた各プロセスはイベント駆動

Puma

  • Ruby製のWebサーバで、並列性が売り
  • GILの無い実行系(JRuby, Rubinius)で最大のパフォーマンスを発揮する
  • メインはスレッドプール
  • 永続的コネクションの処理はイベント駆動

EventMachine

  • Cで実装されたイベント駆動IOライブラリで、Ruby用インタフェースがある
  • メインはイベント駆動
  • 長く時間がかかったり、ブロックするような処理はスレッドプールで処理

以上で、「Working with TCP Sockets 読書メモ」シリーズは終了です。
『Working With TCP Sockets』の感想を簡単に書きます。
前半はソケットプログラミング自体の入門で、システムコールの働きなどがとても丁寧に解説されています。
後半は、ソケットプログラミングを活用したさまざまなアーキテクチャパターンの話で、こちらも非常に興味深かったです。
総じてよく書かれた本で、同著者の『なるほどUNIXプロセス』も読んでみたくなりました。

Working with TCP Sockets 読書メモ 第21章 イベント駆動(Reactor)

Working with TCP Sockets 読書メモ 目次

イベント駆動(Reactor)

概要

  • Reactorパターンに基づいたイベント駆動のパターンが最近流行している
    • 具体的な実装例はNginx, Node.js等
  • このパターンはシングルスレッド・シングルプロセスで、並列性を実現する
  • このパターンでは、コネクションのライフサイクルの各ステージを任意の順番で実行可能なイベントとして扱う
  • 中心となるマルチプレクサ(Reactor)がコネクションのイベントをモニターして処理を起動する
  • 流れは以下のようになる
  1. サーバはソケットでコネクションを待ち受ける
  2. 新しいコネクションを受け付けると、モニター対象ソケットのリストに追加する
  3. サーバは有効なコネクションを監視しつつ、ソケットをlistenする
  4. 有効なコネクションが読み込み可能になった通知を受け取ると、サーバはコネクションからデータを読み取り、必要なコールバックを実行する
  5. 有効なコネクションがまだ読み込み可能であるという通知を受け取ると、サーバはコネクションからデータを読み取り、再びコールバックを実行する
  6. サーバが新しいコネクションを受け付けたら、モニター対象ソケットのリストに追加する
  7. サーバが最初の接続が書き込み可能になったというイベントを受け取ったら、レスポンスが書き込まれる

実装

考察

  • 利点:非常に高性能(数千〜数万コネクションを並列処理可能)
  • 欠点:特殊なプログラミングモデル(Reactorは絶対にブロックしてはならない)

Working with TCP Sockets 読書メモ 第20章 スレッドプール

Working with TCP Sockets 読書メモ 目次

スレッドプール

  • このパターンは、preforkのスレッド版

実装

  • ThreadGroupに含まれるスレッドが実行終了すると、ThreadGroupはスレッドをグループ内から削除する

Working with TCP Sockets 読書メモ 第19章 Prefork

Working with TCP Sockets 読書メモ 目次

Prefork

  • Preforkパターンでは、接続が来る度にforkするのではなく、サーバ起動時にプロセスをまとめて用意する
  1. メインのサーバプロセスがlistenソケットを作成する
  2. メインのサーバプロセスが一群の子プロセスをforkする
  3. それぞれの子プロセスが共有されたソケットから接続を受け取って、独立して処理する
  4. メインのサーバプロセスは子プロセスを監視する
  • メインのサーバプロセス自身は接続を受け付けない点に注意

実装

  • 親プロセスが終了する際は、必ず子プロセスも合わせて終了するように注意する

考察

  • 利点:プロセス数を制限できる、(スレッドに比べて)プロセス単位で分離されている
  • 欠点:(スレッドに比べて)メモリ消費量が多い

Working with TCP Sockets 読書メモ 第18章 スレッドごとの接続

Working with TCP Sockets 読書メモ 目次

スレッドごとの接続

スレッドとプロセス

  • スレッドの方が生成コストが低い
  • スレッドはメモリを共有するので、複数のスレッドで共有されるデータの取り扱いに注意が必要
  • (MRIでは)スレッドはプロセスごとなので、同一の処理系の中で動く
  • (MRIでは)プロセスだけが並行性(concurrency)をもっている

実装

  • 各クライアントのコネクションを別のインスタンスにしている点に注意
  • それぞれのスレッドが1つずつコネクションを処理するよう設計すべき(ベストプラクティス)

考察

  • 利点:プロセスごとの接続よりもパフォーマンスが良い
  • 欠点:(処理によっては)GILによるロックが発生しうる、スレッド数の上限が無い