railsでwebサービスを運営するためにサーバー内でrailsアプリを立ち上げる方法を調べると、なぜかどのサイトでも、nginx+unicornを使っていています。
ローカルでは rails s をして立ち上げるのに、サーバー内では他のものを使うことをちょっと不思議に思うのではないでしょうか。
今回はなぜ rails s で立ち上げず、nginxやunicornを使うのかということが最終的に納得できることを目指して、解説していきたいと思います。
Webサーバーとアプリケーションサーバー
railsやnginxなどの話をする前にまずはwebサーバーとアプリケーションサーバーについて知っておく必要があります。
webサーバーとは
HTTPに則り、HTMLや画像の情報を返してくれるもの、イメージ的には静的なwebサイトで提供されるもの(HTML,CSS,Javascriptなど)が、このwebサーバーで返されるイメージ。
アプリケーションサーバーとは
アプリケーションサーバーは送られてきたリクエストに対して、rubyやphpなどを実行して、動的な処理をした結果を静的な要素に変換してwebサーバーに返すためのもの。つまり、動的なサイトを動かす上で必要なもののうち、静的ではない部分を作ってくれるもののイメージ。
よって、静的な要素のみで作っているサイトだったら、内部的にdbをいじったり、それに合わせた処理をして、htmlを作ったりする必要がないので、webサーバーのみで大丈夫。
webサーバーとアプリケーションサーバーの連携
railsの場合の具体例(わかりやすくするため色々端折っています)
①webサーバーに対して、リクエスト(url)が送られてくる。
②webサーバーに対して送られてきたリクエスト(url)をアプリケーションサーバーが受け取り、どの処理を行えばいいかをroutes.rbを参考にして、実行する。
③dbとの通信や計算などが終わったらそれに対して、viewの~html.erbに情報を埋め込んで静的なhtmlを生成する。
④動的な処理によって生成された静的なhtmlをwebサーバーに返す。
⑤webサーバーはリクエストに対して返ってきた静的な要素をクライアントに返す。
rails sをしたときに何が起きているのか
rails s をするとrackが起動します。rackはアプリケーションサーバで、rackが起動することで、rackアプリケーションとして、railsアプリケーションが起動します。
rackとは
rackはそもそもrubyで書かれた様々なwebフレームワークとwebサーバーをrack自身の柔軟性によって繋いでくれるもので、webサーバ、webフレームワークのどちらが変わってもサイトとしてうまく機能をするようにしてくれているものです。イメージ的にはwebサーバーが動的な要素を取りに行く際にrack内でwebフレームワークを起動させておくことでうまくwebフレームワークにリクエストを送れるといったイメージです。
つまり、rackはrubyで書かれたwebフレームワークをうまく動かすためのアプリケーションサーバということができます。
rails sでrailsを立ち上げたときは特にwebサーバが立ち上がっている訳ではありませんが、rackがもつ柔軟性によってrailsがうまくリクエストを返せるようになっているので、ローカルで立ち上がっています。
結局のところ、rackはrailsの起動をうまく行ってくれて(アプリケーションサーバとしてのメイン)、かつ、webサーバがなくてもうまい具合に処理してくれるもの(おまけ)というイメージで大丈夫です。
(起動時のrackの挙動について詳しく説明しようとするとかなり長くなってしまうので端折ります。こちらを参考にしてください。)
なぜ、rails sで、サービス運営してはいけないのか
rackはあくまで、アプリケーションサーバー。なので、webサーバが持っているような負荷を分散させるための機能などがなく、実運用していく上で、大勢の人がサイトを見たときなどにとても重くなってしまう。
Unicorn + Nginxによるrailsを用いたwebサービス運営
それではここからはUnicornとNginxを用いたrailsの立ち上げについて解説していきたいと思います。
Nginxとは
apacheなどと同じwebサーバの一つ。
ただ、NginxとRackは直接つなげることができないので、Unicornを挟む必要がある。
Nginxを使うメリット
・プロセス数が数千あるので、同時に多くの人に見られても大丈夫。
Unicornとは
UnicornはNginxとRackをうまく繋いでくれるWebサーバとアプリケーションサーバの中間のような存在。
実際Webサーバとしても起動するので、UnicornとRackだけでRailsを動かすことも可能。しかし、プロセス数が少ないため、大勢のアクセスへの対処が難しい。よって、プロセス数が多いwebサーバと合わせて使うことが理想。
Unicornのドキュメントでもnginxと組み合わせることを推奨しているため、Unicornを選ぶ際にwebサーバも自然とNginxになる。
Unicornを使うメリット
プロセスがmaster1つと複数個のworkerに別れていて、masterがソースコードを保持しており、実際に動くのはmasterのプロセスのコピーを持ったworkerプロセス群である。
よって、ソースコードを読み込む必要があるのがmasterだけであり、起動が早くデプロイ時のダウンタイムもない。
また、Nginxがつなぐのはmasterのみなので、masterは各workerにロードバランサーのような形で負荷分散をしながらリクエストを送ることができる。
余談apacheとpassengerについて
apacheも単体ではRackとつなぐことができないので、passengerを使ってrackと接続する。NginxもPassengerを用いてRackと繋げることが可能だが、コンパイルが必要だったりと作業がめんどくさくなってしまう。
apacheとNginxとで比較すると、apacheのメリットは古くから使われているためドキュメントが多いこと、それに対し、Nginxのメリットは、Nginxの方が比較的速く高負荷にも耐えられる。
結論 なぜUnicornとNginxを使ってサーバーを運営するのか
RackだけだとWebサーバがなく、高速な処理や高負荷に耐えることができない。nginxやunicornといったwebサーバを用意することでうまく負荷分散をして、大勢のクライアントからのアクセスに耐えるため。
参考にしたリンク
http://naoty.hatenablog.com/entry/2015/01/10/215538
https://www.marketingbank.jp/special/cat02/173.php
http://d.hatena.ne.jp/h1mesuke/20100205/p1
http://route477.net/d/?date=20080716
http://fujiike.hateblo.jp/entry/2015/08/20/170751
https://qiita.com/sunoko/items/3989865bf915887f8d2b
https://techracho.bpsinc.jp/piichan1031/2010_07_09/2075