こんにちは @sonots です。rails アプリを動かすためのデファクトなアプリケーションサーバーの組み合わせである nginx/passenger のアーキテクチャを解説してみます。
間違っていたら教えてください。※ 以前社内向け(前職)に書いた資料の再掲です。
#いやいや、passenger よりも今は thin だ!unicorn だ!とかいう意見もあるかもしれませんが、デファクトなのは passenger と言っていいんじゃないかなぁ。
典型的なウェブアプリケーション
(1) 例えば Webrick
Webrick の場合は、HTTPリクエストを受け付けるウェブサーバと Rails アプリを実行するアプリケーションサーバ一体化しており、
HTTPリクエスト → Rails アプリの内部処理 → HTTPレスポンス
の処理がシングルプロセスで実行される。並列リクエストを受け付けることはできない
(2) 例えば古きよき CGI
perl CGIで掲示板とか作ったよね。リクエストが来るたびにプロセスが生成される。
(3) 例えば Java Servlet
スレッドだから Java Servlet は速い!と自慢していた。※でもスレッドセーフなプログラムを書かないといけなくなってめんどいよね....
(4) 例えば mod_php
Apache のモジュールと動作するので速い!Javaより格段に速い!と自慢していた。
Passenger (mod_rails)
mod 系(mod_php、mod_perl、mod_python とか)に基本は同じ。
Worker MPM で動作させるのが通常(nginx も worker モデル)
Passenger の本家サイトによると、さらに passenger 部分と同一のアプリケーションコードの部分はメモリを共有化して、各ワーカープロセスが使用するメモリ消費量を抑える工夫をしているらしい(子プロセスとして起動すると、通常メモリを共有できるので、その仕組みを利用しているはず)
nginx/passenger の設定をみてみる
手元の nginx.conf はこうなってました。
worker_processes 1; events { worker_connections 1024; } passenger_max_pool_size 30; passenger_max_instances_per_app 8;
- worker_processes
- HTTPリクエストを処理する (nginx) workerプロセスの数。
- worker_connections
- workerが処理することができる処理の数。スレッド数。つまり、
- max_clients = worker_processes * worker_connections
- passenger_max_pool_size
- 同時に起動できるrailsのインスタンスの最大数。数値を大きくするとたくさんのリクエストを裁けるけどメモリをたくさん使う。デフォルトは6。いろいろ数値を変えて試さないといけない設定。最低でもCPUのコアの数にするべき。2GBのメモリだったら30がおすすめ。VPSでメモリが256MBでMySQLも一緒に動かしてるとかなら2がおすすめ。※ ruby プロセスの数
- passenger_max_instance_per_app
- 一つのアプリで同時に起動できるインスタンスの最大値。passenger_max_pool_sizeより小さい値にしないとダメ。0に設定するとpassenger_max_pool_sizeの設定値まで同時起動可能になる。デフォルト0。
つまりこの設定は、30並列リクエスト、そのうちアプリ単体だと 8並列リクエストしか受け付けないことになる。ただし、静的ファイルに対しては1024並列処理。
CPUが 8コアだったら、8並列が実質ベストなんじゃないかなー。要確認
おまけ:Passenger のステータス確認
以下のコマンドで status やメモリ使用量を調べられます。passenger-memory-stats を使うと子 worker はアプリ自体のロードをしていない(その分のメモリを使っていない)のがわかりますね。
rvmsudo passenger-status passenger-memory-stats
参考サイト
- [1] Passenger オフィシャルサイトhttp://www.modrails.com/documentation/Users%20guide%20Apache.html#spawning_methods_explained
- [2] http://lab.koshigoe.jp/en2ja/passenger/Architectural%20overview.html
- [3] passegner のドキュメントを読む - おもしろWEBサービス開発日記 http://d.hatena.ne.jp/willnet/20100705/1278314320
- [4] Tech learn: Passenger tuning for rails application http://blog.railsupgrade.com/2011/11/passenger-tuning-for-rails-application.html