Rails と Puma と Nginx と
Railsアプリケーションの本番環境を作ったりするときに Puma とか Nginx だとかいう 単語が出てくるわけですが、何となくわかっているつもりでも意外と説明するのが難しいものです。 というわけで質問されても困らないようにまとめます。
各要素について
Ruby on Rails
Rubyで作られたwebアプリケーションフレームワーク。 アーキテクチャはMVCモデルが採用されていて最小限のコードでwebアプリを作成することができる。Modelの部分ではActive Record、Viewの部分ではERBが使われています。
Active Record O/Rマッピングシステム内にある「Active Recordパターン」を実装したもの(理論と実装の名前が同じ) Active Recordの機能として大事なのは以下のところです。
- モデルのデータを表現すること
- モデル間の関連付けをすること
- 関連するモデルの階層関係を表現すること
- DBによって永続化される前にモデルの正当性を検証すること
- オブジェクト指向の書き方でDBを操作すること
ERB 任意のテキストファイルにrubyスクリプトを埋め込むためのライブラリ Rubyの構文を使ってhtmlを繰り返したり、変数の値をテキストとして埋め込むことができます。
Puma
Rubyのアプリケーションサーバ。
rails new
とコマンドを打ってRailsアプリケーションを作成するとこいつがアプリケーションサーバとして設定されている。
Pumaではリクエストの並列処理を実現するためにスレッドが利用されているのが特徴。
開発環境でrails s
とやってサーバを立ち上がっているときに動いているのはこいつ。
Nginx
webサーバー。開発環境のときはPumaで動作させるが、 本番環境などでは一旦Nginxで受け付けてRailsアプリケーションでの処理が必要なものだけを Puma対してリクエストを行う形にする。 Webサーバといえば「Apache」もあげられるが、 こちらのほうが大量のデータ配信や同時接続に耐える設計がなされている。 (同時接続数で言うとApacheの10~100倍くらい可能)
開発環境と本番環境
開発環境でサーバを立ち上げて接続しているときは以下のような形になっています。
しかし本番環境を構築する場合はアプリケーションサーバの前にWebサーバをおきます。Webサーバはアプリケーションサーバの代わりにクライアントからのリクエストを受け付けています。(Nginxがリバースプロキシとして動いている)
わざわざ間にサーバを増やさずに直接アプリケーションサーバを公開すればいいのではとなりますが、 そうもいかないのは当然理由があります。
PumaはWorkerとThreadいう単位でリクエストを受け付けて処理を行います。 設定によって変更可能ですがWorkerのおよび、Threadの数だけ並列でリクエストを処理することができます。 とはいえここでの並列受け付けはせいぜい数十程度が限界です。実際にサービスが公開されれば数百~数千、多ければ数万という単位でリクエストが来る可能性が考えられます。そこで同時接続受付の上限が大きいWebサーバを前において、いい感じにアプリケーションサーバに振り分けてもらうことで多くのアクセスに耐えることができるようにします。
全体を通すと本番環境にアクセスしたときの流れは以下のようになります。
- クラアント来たリクエストをWebサーバが受け取る
- Webサーバはリクエストをアプリケーションサーバに渡す
- アプリケーションサーバはRailsのrouter.rbを見て実際にする処理を決定する
- Railsアプリケーションが処理した結果をアプリケーションサーバに返す
- アプリケーションサーバはWebサーバにレスポンスを返してそれをさらにWebサーバがクライアントに返す
まとめ
最小限の説明だけにすると上のような説明になると思います。 ただ、調べていく中でほかにもいろいろな要素が出てきたので(RackとかUnicornとか、あとRubyの処理系についても)、 実際に動かしたり追加で調べたりしながら理解を深めようと思います。