query: tag:Passenger

環境変数によってRailsアプリの動作を切り替えたいことがあって、

nginx + Passenger で動かしているRailsアプリに環境変数を渡す方法を調べました。

nginx の起動スクリプト(/etc/init.d/nginx)に書いても、

/etc/default/nginx に書いてもうまくいかなかったのですが、

nginx の設定ファイルの location ブロックで

passenger_set_cgi_param で設定することで環境変数が設定できます。

sh>>
passenger_set_cgi_param HOGE fuga;
<<--

これでRailsアプリの中で ENV['HOGE'] で "fuga" という値が取得できるように
なります。

参考ページ

16.3.5. Phusion Passengerが提供するアプリケーション

8.6.1. passenger_set_cgi_param

posted by akanuma akanuma on Sat 22 Nov 2014 at 14:14 with 0 comments

 Passenger + Nginx でアプリケーションを起動しようとしたときに、下記のようなエラーが出ました。

sh>>
git://github.com/nzifnab/msgpack-rails.git (at master) is not checked out. Please run bundle install (Bundler::GitError)
<<--

 もちろん bundle install は実行済みです。msgpack-rails を使用するために、Gemfile に下記のような記述をしてあるのですが、色々調べたところ、Passenger が git からインストールした gem を認識してくれないようです。

ruby>>
gem 'msgpack-rails', :git => 'git://github.com/nzifnab/msgpack-rails.git'
<<--

 bundle install --deployment で解決するという情報も見つけたのですが、これは vendor ディレクトリにgemを持ってくるため結構な時間がかかります。デプロイでは世代管理していて、デプロイ時に新しいディレクトリを作成してデプロイしているので、開発環境のサーバへデプロイするたびに時間がかかるのはちょっと困るので他の方法を探したところ、bundle package
でOKという情報を見つけました。これはgemのキャッシュを vendor ディレクトリに持つもので、すぐに終わります。ただオプションで --all を指定しないと git 経由のgemをキャッシュしてくれないようです。

sh>>
bundle package --all
<<--

とすることで、git からの gem も見つけてくれるようになりました。

(参考サイト)deploying rails3 apps with bundler and phusion passenger: .bundle dir not found

posted by akanuma akanuma on Wed 25 Dec 2013 at 06:01 with 0 comments

 仕事でRailsを使うことになり、APサーバの選定にあたってPuma, Unicorn, Passenger の比較検討を行いました。方法としてはJMeterでAPサーバにデプロイしたRailsアプリケーションに対して負荷をかけられるだけかけるというやり方です。


# 試験環境

試験の環境としては下記の構成です。

  • Ruby2.0, Rails4
  • アプリケーションサーバ:1台(VM)
  • JMeterサーバ:3台(VM)
  • JMeterクライアント:1台(通常の作業PC)
    |caption=サーバ構成
    |
    |hostaname, CPU, 仮想コア数(Per CPU), Memory, Disk, 用途
    |
    |loadtest01, 2, 4, 8192MB, 20GB, APサーバ
    |loadtest02, 1, 1, 4096MB, 20GB, JMeterサーバ
    |loadtest03, 1, 1, 4096MB, 20GB, JMeterサーバ
    |loadtest04, 1, 1, 4096MB, 20GB, JMeterサーバ

# サーバアーキテクチャの比較

各APサーバのアーキテクチャの比較は下記の通りです。

|caption=各APサーバのアーキテクチャの比較
|
|, Puma, Unicorn, Passenger
|
|デプロイモデル, Reverse Proxy, Reverse Proxy, Nginx Module
|Process/Thread, Multi Processes / Multi Threads, Multi Processes / Single Thread, Multi Processes / Single Thread(OSS Edition)
|||, ||, ||, Multi Processes / Multi Threads(Commercial Edition)
|その他特徴, Workerプロセスごとにスレッドを立ち上げる, Pull型(Workerプロセス側からキューのタスクを取得しにいく), トラフィックに応じてプロセス数を自動調整。商用Editionのみマルチスレッド利用可能


# 処理内容

処理内容としては、純粋にAPサーバの処理能力の比較にするため、DBアクセス等はせず、フィボナッチ数列を計算して返す処理を行います。ロジックは書きサイトを参考にしました。

Rubyでメモ化を使ってフィボナッチ数を求める

ruby>>
class StaticPagesController < ApplicationController

def fibonacci
@fibonacci = calc_fibonacci(params[:n].to_i)
end

private

def calc_fibonacci(n)
  if (n < 2)
    return n;
  else
    p2 = 0;
    p1 = 1;
    2.upto(n) { p2, p1 = p1, p2 + p1 }
    return p1;
  end 
end

end
<<--


# JMeterシナリオ

JMeterのシナリオとしては、

  • JMeterスレッド数:100
  • Ramp up:0
  • ループ数:無限ループ
  • 継続時間:5分間

という内容です。
JMeterのシナリオファイルはこちらから取得できます。


# APサーバごとの設定値による差の検証

まずは各APサーバごとに、設定値の変更による差を検証しました。


## Puma

|caption=Puma検証
|
|ワーカプロセス数, スレッド数, サンプル数, 平均値(msec), 中間値(msec), 90%LINE (msec), 最小値(msec), 最大値(msec), スループット(/sec), KB/sec, エラー数
|
|1, 500, 43079, 2090, 1978, 2379, 129, 2519, 141.68, 414.67, 多発
|100, 8, 241811, 365, 57, 1071, 6, 46414, 799.43, 2339.49, 0
|100, 32, 243620, 362, 60, 1136, 6, 16890, 805.37, 2356.83, 32
|64, 32, 242825, 365, 51, 1355, 7, 103157, 802.35, 2347.94, 1
|32, 32, 241934, 366, 46, 760, 6, 252504, 798.24, 2335.89, 0
|16, 64, 237270, 373, 31, 339, 6, 298546, 782.00, 2288.34, 0
|16, 96, 231996, 382, 37, 644, 6, 241748, 762.49, 2231.26, 0

  • ワーカプロセス数1のケースでは全くCPUを使い切れていませんが、他のケースではCPUを使い切った状態で動いていました。
  • スレッド数を増加させてもリソースの使用量はあまり変化しませんでしたが、プロセス数を増やすと使用量がかなり増えます。
  • メモリに余裕があってもCPUが振り切る方が早いです。

## Unicorn

|caption=Unicorn検証
|
|ワーカプロセス数, サンプル数, 平均値(msec), 中間値(msec), 90%LINE (msec), 最小値(msec), 最大値(msec), スループット(/sec), KB/sec, エラー数
|
|1, 4294, 11345, 572, 50553, 77, 176247, 11.74, 34.54, 433
|8, 8686, 6026, 562, 13721, 77, 141193, 22.15, 65.15, 389
|32, 42943, 1465, 325, 2844, 51, 183552, 103.48, 304.38, 280
|64, 191254, 440, 170, 375, 26, 115819, 498.54, 1466.46, 48
|96, 247191, 360, 170, 261, 49, 82454, 773.58, 2275.69, 3
|128, 256050, 343, 252, 452, 13, 20587, 836.00, 2459.82, 0
|160, 254117, 347, 291, 537, 15, 8825, 835.54, 2458.54, 0
|192, 252158, 349, 302, 588, 13, 5746, 833.94, 2453.87, 0
|224, 229723, 383, 275, 592, 9, 299799, 697.12, 2045.15, 2

  • ワーカプロセス数が1の場合は1CPUしか使われない
  • ワーカプロセス数をコア数と同じ8にした場合でも、すべてのコアが使われるわけではない
  • ワーカプロセス数をコア数の4倍の64まで増やすとかなりCPUが使われるようになってきて、128まで増やすとCPUはほぼ使い切られて、メモリの使用率も高くなる。
  • ワーカプロセス数を192まで増やした時点でメモリもほぼ使い切られ、224まで増やすとメモリが足りなくなり、Swapが発生して遅くなる。

## Passenger

|caption=Passenger検証
|
|プロセス数, サンプル数, 平均値(msec), 中間値(msec), 90%LINE (msec), 最小値(msec), 最大値(msec), スループット(/sec), KB/sec, エラー数
|
|1, 65188, 1376, 1282, 1325, 1224, 8690, 215.15, 646.07, 0
|8, 245153, 360, 355, 368, 297, 2441, 810.57, 2433.99, 0
|16, 246737, 357, 353, 381, 279, 2339, 815.77, 2448.77, 0
|24, 241165, 366, 360, 391, 281, 2414, 797.27, 2392.30, 0

  • プロセス数が1だと4コアしか使われていない
  • プロセス数をコア数と同じにするとどのコアもかなり使われるようになる。メモリは余裕あり。
  • プロセス数をコア数以上に増やしていってもCPU, メモリの使用率はあまり変化しない。CPUは80%まで使われることが多いが、アイドルが10%前後残っていて、使い切ることはない

# 各APサーバの最適値同士を比較

各APサーバの最適値同士を比較して、使用するAPサーバを決定する

|caption=総合
|
|APサーバ, サンプル数, 平均値(msec), 中間値(msec), 90%LINE (msec), 最小値(msec), 最大値(msec), スループット(/sec), KB/sec
|
|Puma, 241811, 365, 57, 1071, 6, 46414, 799.43, 2339.49
|Unicorn, 252158, 349, 302, 588, 13, 5746, 833.94, 2453.87
|Passenger, 246737, 357, 353, 381, 279, 2339, 815.77, 2448.77

  • Pumaはスループットが一番低いのに加えて最大値、90%LINEの遅さ、不安定さで候補から除外。
  • Passengerは安定しているが最小値が他の2つに比べて大きい。90%LINE、最大値は優秀。
  • Unicornはスループットが一番大きいのと、最小値、平均値も悪くない。最大値、90%LINEがPassengerと比 べると遅いのが懸念点。

|caption=定数スループットタイマを使って実際のアクセス数に近い負荷でUnicornとPassengerを比較
|
|APサーバ, サンプル数, 平均値(msec), 中間値(msec), 90%LINE (msec), 最小値(msec), 最大値(msec), スループット(/sec), KB/sec
|
|Unicorn, 23075, 12, 10, 13, 4, 116, 75.32, 221.50
|Passenger, 23092, 11, 9, 12, 5, 118, 75.38, 226.67

  • UnicornとPassengerでほぼ差はなし
  • Passengerは最初の比較時に他と比べて最小値が遅いことが懸念だったが、実際の状況に近いアクセス数では 問題なく、Unicornが負荷が低い状態でもメモリリソースを消費するのに対してPassengerはリソースの消費が少ないこと から、Passengerを第一候補と考える。

# 検証時の問題点

検証時に発生した問題点を参考までに記載しておきます。


## Passenger
  • デフォルトの状態で負荷をかけたところ、下記のようなエラーが多発してHTTPステータスコード 503が返される。

sh>>
[ 2013-11-20 12:21:13.0578 17419/7fbbbc9da700 Pool2/Group.h:331 ]: Request queue is full. Returning an error
<<--

リクエストのQueueがあふれたことによるもののようです。Queue のサイズのデフォルトは100なので、無制限にするために passenger_max_request_queue_size を0に設定したところ、エラーは出なくなりました。


## Unicorn
  • Nginxとの連携をUnixドメインソケットで行う設定で負荷をかけたところ、下記エラーが多発。

sh>>
2013/11/20 11:32:35 [error] 27462#0: *622742 connect() to unix:///home/test_user/server-proto/unicorn.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 192.168.51.234, server: loadtest01.test.com, request: "GET /fibonacci?n=1000 HTTP/1.1", upstream: "http://unix:///home/test_user/server-proto/unicorn.sock:/fibonacci?n=1000", host: "loadtest01.test.com:3090"
<<--

下記サイトなどを参考に、TCPポートによる連携に変更しました。

[http://www.faultserver.com/q/answers-need-to-increase-nginx-throughput-to-an-upstream-unix-soc ket-linux-kernel-tun-398972.html](http://www.faultserver.com/q/answers-need-to-increase-nginx-throughput-to-an-upstream-unix-soc ket-linux-kernel-tun-398972.html)

変更後に負荷をかけたところ、エラーは概ね解消しました。負荷をかけ続けていると、件数は少なくなったもののエラーが発生しました。HTTPステータスコードは 502 Bad Gateway

sh>>
2013/11/20 14:45:29 [error] 25979#0: *254606 upstream prematurely closed connection while reading response header from upstream, client: 192.168.51.232, server: loadtest01.nubee.com, request: "GET /fibonacci?n=1000 HTTP/1.1", upstream: "http://127.0.0.1:3070/fibonacci?n=1000", host: "loadtest01.test.com:3090"
<<--

sh>>
[2013-11-20 14:44:09.109250] ERROR worker=114 PID:26737 timeout (31s > 30s),
killing
[2013-11-20 14:44:09.119595] ERROR reaped #<Process::Status: pid 26737 SIGKILL
(signal 9)> worker=114
[2013-11-20 14:44:10.140398] INFO worker=114 ready
<<--

検証のためにUnicorn側のタイムアウト設定を大幅に増やしました。30秒 → 300秒に変更。Nginxの設定にも下記を追加しました。

sh>>
send_timeout 300;
proxy_connect_timeout 300;
proxy_read_timeout 300;
<<--

これでひとまずエラーは回避できました。。スループットの検証のためにタイムアウト値を大きくしていますが、実際の環境ではタイムアウト値は小さく設定する必要があります。

posted by akanuma akanuma on Sun 8 Dec 2013 at 00:06 with 0 comments

長いこと不安定だったので一時期 mod_proxy_balancer + mongrel_cluster
に逃げていましたが、
@yuumi3
から2.2.11で直ったよという情報をいただいたので passengerに戻してみました。

今のところは安定している感じです。

posted by genki genki on Wed 28 Apr 2010 at 02:14 with 0 comments

しばらく前から安定性が悪くなってきたのですが、ここに来て頻繁にPassengerのプロセスが暴走するようになってきました。

  • ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-linux]
  • Passengerのバージョンは2.2.8
  • Rails 2.3.5

プログラムやシステム構成はここしばらくほとんど変えておらず、トラフィックも大きな変動はないので、うわさのEC2のサービス劣化の影響でしょうか。

posted by genki genki on Thu 25 Feb 2010 at 02:06 with 0 comments

小ネタです:Passengerのステータス確認

shell>>
passenger-status
----------- General information -----------
max = 6
count = 6
active = 4
inactive = 2
Waiting on global queue: 43
<<--
global gueueが43もあるのは異常で、こういう場合はapacheをrestartする。

上記の他にBacktracesやDomainsなどの情報を表示してくれます。

###passenger-statusコマンド

http://www.modrails.com/documentation/Users%20guide.html

posted by satoko satoko on Thu 4 Jun 2009 at 02:50 with 0 comments

Passengerは非常に便利なのですが、
通常の設定では、アプリケーションへのアクセスが無い状態が5分程度続くと、プロセスがkillされてしまい、次回にアクセスする時に時間がかかるようになります。

これを回避するためには、httpd.confなどで、以下のように指定します。

pre>>
PassengerPoolIdleTime 0
<<--

これで、プロセス数の限界に達して追い出されるまで、Idle時間によってkillされる事は無くなります。

See Also

posted by genki genki on Sat 28 Mar 2009 at 20:32 with 0 comments

I am using merb with passenger on our production server.
The passenger is going well in most of cases.
But if dependent gems have been updated, it becomes acting up when it got restarted.
After I encountered such situations several times, I decided to begin investigation about the issue.

Detail of the issue is as follows.

  • My merb app becomes causing errors after restarting of passenger by "touch tmp/restart.txt" if dependency gems were updated and they have no compatibility.
  • Even if the gems were compatible, my merb app kept using old gems until apache is reloaded.
  • pids were changing successfully while restarting.
  • /etc/init.d/apache reload can refresh everything as expected.
  • "touch tmp/restart.txt" can't.

I wonder there is the master of master processes which keeps LOAD_PATH and it is refusing to use new gems.
I am thinking I should investigate the Rack.

Update

Finally, the issue was solved!

The solution is found here

posted by takiuchi takiuchi on Sat 17 Jan 2009 at 22:41 with 0 comments

PassengerはRackに対応しているので、Merbも動かすごとができます。

以下のように、Merbアプリケーションのディレクトリの直下に
config.ruファイルを作成して置くだけです。

ruby>>
require 'rubygems'
require 'merb-core'
Merb::Config.setup(:merb_root => ".",
:environment => ENV['RACK_ENV'])
Merb.environment = Merb::Config[:environment]
Merb.root = Merb::Config[:merb_root]
Merb::BootLoader.run

Uncomment if your app is mounted at a suburi

#if prefix = ::Merb::Config[:path_prefix]

use Merb::Rack::PathPrefix, prefix

#end

run Merb::Rack::Application.new
<<--

ちなみに ru はRack Upの事だと思われます。

ハマった点として、
Merbアプリのひな形の"/"で表示される画面は、エラーページなので、
production環境のPassengerで動かすとエラーとして扱われてしまいます。
なので、動作確認する場合、
なにかしらコントローラを作ってから試す必要があります。

posted by genki genki on Thu 20 Nov 2008 at 12:04 with 0 comments

たびたび参照したくなるのでチートシート的にまとめておきます。
より詳細な情報は
Phusion Passenger users guide
をご確認ください。

  • PassengerRoot <directory>
  • RailsBaseURI <uri>
  • RailsAutoDetect <on|off>
  • RailsAllowModRewrite <on|off>
  • RailsRuby <filename>
  • RailsEnv <string>
  • RailsSpawnMethod <string>
  • RailsMaxPoolSize <integer>
  • RailsPoolIdleTime <integer>
  • RailsMaxInstancesPerApp <integer>
  • RailsUserSwitching <on|off>
  • RailsDefaultUser <username>

** See Also **

posted by genki genki on Tue 2 Sep 2008 at 05:38 with 0 comments

http://blog.dreamhost.com/2008/05/13/passenger-for-ruby-on-rails/

話題になっていたPassengerですが、Dreamhostで採用されました。masuidriveさんもオススメのようなので、ぜひ使ったみたいです。

http://rails20.jp/2008/04/passenger/
http://www.moongift.jp/2008/04/passenger/
http://blog.masuidrive.jp/index.php/2008/04/12/deploy_rb_and_apache_conf_generator_for_mod_rail/

posted by satoko satoko on Thu 15 May 2008 at 05:24 with 0 comments