調べるとどんどん深みにハマっていきます。それは決して悪い事ではなく、知識が増え、理解が深まり、自分でコントールできる範囲が増える事に、高揚感を覚えます。ただ掘れば掘るほど分からないことは出てくるので、一度区切りとして、自分の言葉でここにまとめておきます。
この記事ではNginxとUnicornを用いて、Rails専用のWebサーバーを立てる為に、それぞれの役割などを理解する過程で得た情報をまとめています。具体的な実装方法や設定などについては記載しません。
また記事内では曖昧で抽象的な表現が見受けられると思いますが、それは現状ではそのような表現以上の理解が進んでいない為です(ダサい)。
この記事における主な目的は以下の通りです。
- Nginx × Unicorn × Rails においてUnicornが必要な理由
- NginxとUnicornの補完関係の概要
参考
Unicorn
Rack
まずUnicornの理解の前に、Rackというアプリケーションサーバーに関して軽く触れておきます。
RackとはRubyで作られたフレームワーク(Railsやsinatra)とWebサーバーを繋ぐためのアプリケーションサーバーです。WebサーバーからのリクエストをRailsに伝え、そのレスポンスをwebサーバーへ返す仲介役を担います。
Unicornの概要とその特徴
Unicornは、Rack専用のWebサーバーです。Webサーバーである為、Nginxを利用せずともクライアン(iPhoneなど)からのリクエストに対し、Unicorn単体でレスポンスを返すことは可能です。
しかし、Unicornでは「ブロッキングI/Oモデル」で実行されているため、クライアントからのリクエストを非同期で処理することができません(ここからが怪しい)。
あるユーザーが不安定な通信環境(3Gなど)でリクエストしてきた場合、その処理が終了するまでは、それ以外のリクエストに対応できなくなります。2つのワーカープロセスが存在していても、重い処理が終わるまでは、その他のリクエストに対し、実質1つのワーカープロセスで対応する状況になってしまいます。
ブロッキングI/Oモデル
I/O処理時に対象が準備完了になるまで待機し続けること。(ここに関しては理解を深める必要あり。
Unicornの動作
上で既に触れましたが、Unicornではマルチプロセスによるclusterではなく、forkを用いたmaster-slaveというアーキテクチャを採用しており、マスタープロセスとワーカープロセスという概念があります。
マスターはアプリケーションのインスタンスを持つ唯一のプロセスで、複数のワーカープロセスを生成し、所有します。マスタープロセスがワーカープロセスを生成することをフォークと呼びます。
つまりUnicornにおいて処理を裁いているのは、マスタープロセスをフォークしたワーカープロセスが処理しています。
Unicornの設定は大別して「変数の設定」と「フォーク前後の処理」に分けられます。これに関しては、参考記事の2つ目が詳しく解説しています。
何故Nginxが必要か
NginxもWebサーバーの一つです。Nginx × Unicornはどちらもwebサーバーです。
なぜNginxを用いるかと言うと、先ほど説明したブロッキングI/Oモデルを採用した大量のアクセスを裁く事が苦手なUnicornに対し、Nginxはイベント駆動型モデルを採用しており、大量のアクセスを裁く事が得意である特徴を所持しています。
この事から大量のアクセスが苦手なUnicornに対し、高負荷に対応できるNginxを補完した2つのWebサーバーを用いる事で、
クライアント ⇄ Webサーバー(Nginx × Unicorn) ⇄ Rails
という構図を実現しているのです(多分)。
他に何の理解が必要か
それぞれのwebサーバーのアーキテクチャ(?)・特徴に関しての理解が必要であると考えています。
I/Oモデルやイベント駆動型、これらの理解にはLinuxの理解などが必要であり、中々苦戦しています。(同時に面白くもありますが...)
まだまだ知識不足ですが、最後までお読み頂き、ありがとうございました。
間違い等ご指摘いただけると幸いです。