Apache Passengerの設定項目について調べた
PassengerはRailsを動かす事ができるアプリケーションサーバである。
Apache版の設定項目について調べたので自分用の備忘録として残しておく。
バージョン
Passenger-4.0.37
http://www.modrails.com/documentation/Users%20guide%20Apache.html
Configuring Phusion Passenger
PassengerRoot
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerroot_lt_directory_gt
apacheのpassengerモジュールの置いてあるディレクトリを指定する。
普通はインストーラを実行した時に表示されるのでそれを使えばよい。rubyのインストール場所をかえた場合などはこちらの値も変更する必要がある。
PassengerDefaultRuby
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerDefaultRuby
アプリケーションとInternalHelper(例:PassengerPreStart)が使うRubyインタプリタを指定する。
PassengerRoot同様にインストーラ実行時に表示されるのでそれを使えば良い。
Deployment options
PassengerEnabled
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerEnabled
指定したコンテクストでPassengerを無効化出来る。
PassengerRuby
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerRuby
VirtualHostやDirectory等のコンテクストで使うRubyインタプリタを指定できる。PassengerDefaultRubyをOverrideできる。
この設定ができることにより、アプリケーション毎に使うRubyのバージョンを混在することが可能になる。
ただし、InternalHelperスクリプトは常にPassengerDefaultRubyで指定されたインタプリタを使う。
PassengerPython
PassengerRubyと同じ。
PassengerNodejs
PassengerRubyと同じ。
PassengerAppEnv
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerAppEnv
下記の環境変数を指定する。stagingなど指定することでアプリケーションの環境を切り替える事ができる。
RAILS_ENV
RACK_ENV
WSGI_ENV
NODE_ENV
PASSENGER_ENV
RailsEnv
PassengerAppEnvのエイリアス。
RackEnv
PassengerAppEnvのエイリアス。
PassengerAppRoot
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerAppRoot
アプリケーションのルートディレクトリを指定する。
デフォルトはDocumentRootの親ディレクトリ
PassengerRestartDir
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerrestartdir_lt_directory_gt
アプリケーションを再起動するためにはrestart.txtをtouchする必要がある。
restart.txtを配置するディレクトリを指定する。
デフォルトはPassengerAppRoot配下のtmpディレクトリ。
PassengerRollingRestarts(enterprise限定)
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerRollingRestarts
OSS版の最大の弱点と言っても過言ではないのがdeploy後のダウンタイムである。Rolling Restartをonにすることでunicornのようにゼロダウンタイムdeployが可能になる。
通常のRestartの場合、workerプロセスを一度全てshutdownしてから新しいプロセスを作るのに対して、1プロセスずつ入れ替えてdeployしてくれるのがRollingRestartsである。
Phusion Passenger Enterprise: rolling restarts from Phusion on Vimeo.
PassengerResistDeploymentErrors(enterprise限定)
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerResistDeploymentErrors
DeployしたコードにSyntaxErrorなどがあった場合、壊れたコードは実際には使われずにDeploy前のバージョンが使われてDeployに失敗した事がログに出力される。
この機能はRollingRestart機能が有効になっていないと作動しないので注意が必要だ。
Phusion Passenger Enterprise: deployment error resistance from Phusion on Vimeo.
Process spawning options
PassengerSpawnMethod
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerSpawnMethod
worker生成の方法を指定する。
smartとdirectがありsmartはアプリケーションコードをcacheするために生成がdirectに比べて速いが、アプリがMemcachedとのコネクションを持っている場合などは注意が必要になる。
RailsでMemcachedを使っている場合は下記設定をアプリのコードに書いてworkerプロセス毎に再接続を行う必要がある。
if defined?(PhusionPassenger) PhusionPassenger.on_event(:starting_worker_process) do |forked| if forked # We're in smart spawning mode. reestablish_connection_to_memcached else # We're in direct spawning mode. We don't need to do anything. end end end
PassengerLoadShellEnvvars
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerLoadShellEnvvars
シェルがbashの場合、環境変数をロードする。
Security options
PassengerUserSwitching
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerUserSwitching
全てのPassengerプロセスを同一のユーザーにしないことでセキュリティを担保する
PassengerGroup
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerGroup
Passengerのプロセスはデフォルトではconfign/enviroment.rbかconfig.ruファイルの所有グループを引き継ぐが、
この設定を入れることで上書きすることができる。
PassengerDefaultUser
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerDefaultUser
user switching supportが失敗した またら無効の場合に、このオプションで指定したユーザーでプロセスが動く。
デフォルトはnobody。
PassengerDefaultGroup
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerDefaultGroup
user switching supportが失敗した またら無効の場合に、このオプションで指定したグループでプロセスが動く。
デフォルトはPassengerDefaultUserのグループ。
PassengerFriendlyErrorPages
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerFriendlyErrorPages
Passengerを立ち上げる時にDBの設定が間違っていたりすると立ち上げに失敗してエラーの原因をbacktraceとともに下記のような画面を表示してくれて嬉しいのだが、
プロダクション環境でこのメッセージを表示してしまうとサーバの情報を外部に漏らす可能性がある。この設定をoffにすることで非表示にできる。
Resource control and optimization options
下記動画にあるように、Enterprise版だとより柔軟なリソースコントロールが可能になる。
Phusion Passenger Enterprise: resource control from Phusion on Vimeo.
PassengerMaxPoolSize
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMaxPoolSize
1つのサーバで立ち上がるWorkerプロセスの最大値を設定する。
マルチスレッドモデルを使わない場合はこの数値がPassengerが同時に処理することができるリクエスト数になる。
サーバのメモリが足りない場合は数値を下げる必要がある。
デフォルトは6。
3に指定した場合、立ち上がるworkerプロセスはサーバ内で最大でも3個までとなる。
$ ps aux | grep "[P]assenger RackApp" u 3778 5.0 6.3 141180 109172 ? Sl 07:20 11:25 Passenger RackApp: /var/www/test-app/current u 27640 3.6 6.3 141560 109604 ? Sl 03:21 16:54 Passenger RackApp: /var/www/test-app/current u 29392 3.9 6.4 142200 111356 ? Sl 04:07 16:38 Passenger RackApp: /var/www/test-app/current
QueueSizeという名前が混乱を招くがworkerプロセスの数を意味する。
設定の目安はPhusionのブログに書いてあり、
http://blog.phusion.nl/2013/03/12/tuning-phusion-passengers-concurrency-settings/
シングルスレッドの場合の計算式:
max_app_processes = (TOTAL_RAM * 0.75) / RAM_PER_PROCESS サーバのメモリが1.7GBで1プロセスのメモリ使用が100MBの場合は: 12.75 = (1700MB * 0.75) / 100MB
マルチスレッドの場合の計算式:
max_app_threads_per_process = ((TOTAL_RAM * 0.75) - (NUMBER_OF_PROCESSES * RAM_PER_PROCESS * 0.9)) / (RAM_PER_PROCESS / 10) NUMBER_OF_PROCESSESはRuby(MRI)の場合CPUの数で考えていいようだ(JRUBYやRubiniusの場合は1で考える)。 Rubyを使っていてサーバのCPUが2でメモリが1.7GBで1プロセスのメモリ使用が100MBの場合は: 109.5 = ((1700MB * 0.75) - (2 * 100MB * 0.9)) / (100MB / 10)
※32bitシステムの場合はmax_app_threads_per_processは200より大きくするべきではない
上記の計算結果を設定してあげればよい。
#シングルスレッドの場合: PassengerMaxPoolSize 12 # マルチスレッドの場合 PassengerMaxPoolSize 2(CPUの数) PassengerThreadCount 109
PassengerMinInstances
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMinInstances
全体または1つのアプリケーションで立ち上げるWorker数の下限をglobalとアプリケーションどちらにでも指定する事が可能。
PassengerMaxInstances(enterprise限定)
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMaxInstances
全体または1つのアプリケーションで立ち上げるWorker数の上限をglobalとアプリケーションどちらにでも指定する事が可能。
例えば、websiteとblogをvirtulhostに設定していてwebsiteへのアクセスが多い場合は下記のように設定することでwebsiteの同時実行処理リクエスト数を2にするといったカスタマイズが可能である。
PassengerMaxRequestQueueSize 3 <VirtualHost *:80> PassengerMaxInstances 2 RailsEnv production ServerName www.hakutoitoi.com </VirtualHost> <VirtualHost *:80> PassengerMaxInstances 1 RailsEnv production ServerName blog.hakutoitoi.com </VirtualHost>
プロセスリスト:
$ ps aux | grep "[P]assenger RackApp" u 3778 5.0 6.3 141180 109172 ? Sl 07:20 11:25 Passenger RackApp: /var/www/website/current u 27640 3.6 6.3 141560 109604 ? Sl 03:21 16:54 Passenger RackApp: /var/www/website/current u 29392 3.9 6.4 142200 111356 ? Sl 04:07 16:38 Passenger RackApp: /var/www/blog/current
PassengerMaxInstancesPerApp
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengermaxinstancesperapp_lt_integer_gt
一つのアプリケーションで立ち上げるWorkerプロセスの上限をグローバルで指定する事が可能。
PassengerMaxInstancesのようにアプリケーションごとに柔軟にプロセス数を指定することはできないので全てのアプリケーションの最大プロセス数は同一になる。
PassengerMaxRequestQueueSize 2 PassengerMaxInstancesPerApp 1 <VirtualHost *:80> RailsEnv production ServerName www.hakutoitoi.com </VirtualHost> <VirtualHost *:80> RailsEnv production ServerName blog.hakutoitoi.com </VirtualHost>
プロセスリスト:
$ ps aux | grep "[P]assenger RackApp" u 3778 5.0 6.3 141180 109172 ? Sl 07:20 11:25 Passenger RackApp: /var/www/website/current u 27640 3.6 6.3 141560 109604 ? Sl 03:21 16:54 Passenger RackApp: /var/www/blog/current
PassengerPoolIdleTime
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerPoolIdleTime
1つのwokerが設定した秒数の間idle状態が続いた場合、そのworkerはメモリ節約のためshutdownされる。
デフォルトは300秒。
idle状態がどのくらい続いてるかはpassenger-statusコマンドのLast usedの項目で確認できる。
$ sudo /usr/local/bin/passenger-status | grep -B 1 "Last used" * PID: 27640 Sessions: 0 Processed: 14570 Uptime: 9h 10m 6s CPU: 3% Memory : 103M Last used: 23s ago * PID: 29392 Sessions: 0 Processed: 14477 Uptime: 8h 24m 0s CPU: 4% Memory : 104M Last used: 4m 40s ago
この例だとPID29392のworkerがidle状態のまま4分40秒経っているためもうすぐshutdownされる。
PassengerMaxPreloaderIdleTime
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMaxPreloaderIdleTime
workerを生成・破棄するSpawnerプロセスがshutdownするまでのidle時間の設定。
デフォルトは300秒で、その間workerプロセスに変動がなければshutdownされる。
PassengerStartTimeout
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerstarttimeout_lt_seconds_gt
workerプロセスの開始に設定した秒数以上かかったら失敗する。
デフォルト90秒。
PassengerConcurrencyModel(enterprise限定)
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerConcurrencyModel
マルチスレッドモデルを有効にできる。
PassengerThreadCount(enterprise限定)
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerThreadCount
マルチスレッドが有効な時に一つのプロセスがいくつのスレッドを使えるようにするか設定する。
デフォルトは1。
PassengerMaxRequests
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMaxRequests
ここに設定したリクエスト数を処理するとwokerプロセスが再起動する。
アプリケーションがメモリリークを起こしている場合には必要な設定だろう。
デフォルトは0で無効になっている。
PassengerMaxRequestTime(enterprise限定)
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMaxRequestTime
リクエストの処理時間が設定値を超えたらworkerを再起動する。
デフォルトは0で無効になっている。
リクエストの処理に時間がかかりすぎてアプリケーション全体がつまって止まってしまう危険性を減らす事ができる。
下記の設定をすると/expensive_computationへのリクエストだけtimeoutまでの時間を伸ばせるといった柔軟な設定を行える。
<VirtualHost *:80> ServerName www.example.com DocumentRoot /webapps/my_app/public PassengerMaxRequestTime 2 <Location /expensive_computation> PassengerMaxRequestTime 10 </Location> </VirtualHost>
この設定が必要になる時は大体アプリケーションが遅いことに問題があるので、問題を特定して迅速に修正すべきだろう。
PassengerMemoryLimit(enterprise限定)
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMemoryLimit
ここに指定したメモリ数を超えるメモリをwokerプロセスが使うと再起動する。
アプリケーションがメモリリークを起こしている場合には必要な設定だろう。
デフォルトは0で無効になっている。
PassengerStatThrottleRate
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerstatthrottlerate_lt_integer_gt
設定ファイル(config/envrironment.rb)や再起動ファイル(restart.txt)をチェックするタイミングを指定できる。
0の場合は各リクエストを処理するタイミングで行う。
秒数を指定した場合はその秒数毎にチェックする。
PassengerPreStart
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerPreStart
デフォルトではPassengerは最初にリクエストがあるまでプロセスをstartさせない。この設定を入れることでapacheを起動した時に指定したURLだけはアクセスがなくてもアプリケーションを事前にstartしてくれる。
PassengerHighPerformance
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerHighPerformance
onに設定すると少し高速化されるがmod_rewriteやmod_autoindexなどのモジュールが使えなくなる。
Connection handling options
PassengerBufferUpload
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerBufferUpload
onの場合、POSTでアップロードされたデータはアプリケーションに送られる前にバッファされる。遅いクライアントからのアップロードを守るが、アップロード進捗を追跡する機能は使えなくなる。
デフォルトはon。
PassengerBufferResponse
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerBufferResponse
onの場合、apacheにレスポンスをバッファさせる。
apache版のPassengerの場合、2つのレスポンスバッファリングシステムが有効である。
- Apache response buffering system(PassengerBufferResponseでon/offできる)
- Phusion Passenger response buffering system(この設定はPassengerBufferResponseがoffでも常に有効である)
基本的にはPassengerのほうがバッファしてくれるので遅いクライアントからの攻撃があってもoffで問題はない。
もし何がしかの理由でapacheレベルのバッファリングをしたい場合は、このオプションをonにすることで有効にすることができる。
注意して欲しいのはこのオプションをonにした場合はストリーミングレスポンスを作るのが不可能になること。
下記のコードは1秒毎にレスポンスを返すコードだがPassengerBuggerResponseをonにした場合は10秒後に全体のレスポンスを返す挙動になってしまう、offの場合なら期待通りに動く。
render :text => lambda { |response, output| 10.times do |i| output.write("entry #{i}\n") output.flush sleep 1 end }
※大きいサイズのレスポンスを返す場合はこの設定はoffにすべきだろう、なぜならレスポンスはメモリにバッファされるのでメモリ使用量が極端に大きくなってしまう。
PassengerErrorOverride
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerErrorOverride
400番以上のエラーページをPassengerデフォルトのものから自分の好きなページに変更できる。
PassengerMaxRequestQueueSize
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMaxRequestQueueSize
全てのwokerがリクエスト処理中の状態で新規のリクエストがくるとリクエストキューに格納されてidleになったwokerが順次このキューにたまったリクエストを処理するのだがこのキューの最大サイズをアプリケーション毎に設定できる。
デフォルトは100で、100を超えたらキューにはためずにクライアントに503エラーを返すようになる。
この動作は非常に重要でアプリケーションになんかしらの問題が起きている事を把握できる。例えば:
- PVがいきなり増加した
- フルテーブルスキャンやフルインデックススキャン等の非常に時間のかかる処理を行うようになった
- 巨大なテーブルにインデックスの追加を行ったため、テーブルにWRITEロックがかかり全てのwokerが更新処理中でロック解除待ちになっている
などなど。
キューにたまっているリクエスト数はpassenger-statusコマンドで知ることができる。
$ sudo /usr/local/bin/passenger-status | grep "Requests in queue" Requests in queue: 0
この例ではキューはたまってないことを意味する。
また下記設定を追加することで503エラーページをカスタマイズすることが可能である。
PassengerErrorOverride on ErrorDocument 504 /error504.html
Compatibility options
PassengerResolveSymlinksInDocumentRoot
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerResolveSymlinksInDocumentRoot
Passenger-2.2以降の場合、DocumentRootがシンボリックリンクだった場合にconfig/environment.rbを探せないが、
この設定をonにすることで2.2以前の動作になるので探せるようになる。
新しいアプリケーションに関してはDocumentRootはシンボリックにしないほうがいいだろう。
PassengerAllowEncodedSlashes
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerallowencodedslashes_lt_on_off_gt
スラッシュがURLencodeされたリクエストを処理できるようにする。
Logging and debugging options
PassengerLogLevel
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerLogLevel
ログレベルを指定する。
- 0: errorとwarningのみ
- 1: important debugも表示
- 2: debugをもっと表示
- 3: さらにdebugを表示
PassengerDebugLogFile
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerdebuglogfile_lt_filename_gt
デバッグとエラーログを出力するファイルを変更できる。
デフォルトではapacheのグローバルなerrorlogになっている。
PassengerDebugger(enterprise限定)
http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerdebugger_lt_on_off_gt
Passengerでデバッガを使うことができる。
Rails開発の場合、ローカルのmacでwebrickを立ち上げて行う事が多い。その時にデバッグするのと同じようにPassengerを使っている場合でもデバッグできるようになる。
デフォルトはoff。
Phusion Passenger Enterprise: live IRB and debugging console from Phusion on Vimeo.
Advanced options
PassengerTempDir
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerTempDir
Passengerが使うtmpファイルを置くディレクトリを指定できる。
デフォルトは/tmp。
この値を変更している場合は、passenger-status等のコマンドを使う場合に環境変数でディレクトリを指定しなければならない。
export PASSENGER_TMPDIR=/my_temp-dir sudo -E passenger-status # The -E option tells 'sudo' to preserve environment variables.
PassengerUploadBufferDir
http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerUploadBufferDir
大きいファイルをPOSTされた場合に、Passengerはデータをファイルにバッファする。
そのディレクトリを指定する。
デフォルトはシステムのtmpディレクトリのサブディレクトリになる(PassengerTempDirを指定している場合はそのサブディレクトリ)。
Deprecated or removed options
Deprecatedなので割愛する。