2

私たちの Rails アプリケーションには、サーバーにデプロイする 2 つの環境 (ステージング環境とデフォルトの本番環境) があります。

staging.rb ファイルは、config/environments フォルダーから production.rb のコピーです。2 つの違いは、whiny nil が true に設定されていることです。

config.whiny_nils = true

Rails アプリケーションは主にその API に使用されるため、開発者が使用できるように社内のステージング サーバーの 1 つで実行しました。これは、ほぼ4か月間問題なく機能しました。実稼働サーバーに転送するときが来ると、POST または PUT が大きな (場合によっては非常に大きな) 本体で受信されるたびに、スタックが一貫してクラッシュし始めました。2 つのサーバー間でテストすると、同じ要求がステージング サーバーによって完全に処理されました。

クラッシュ/ハングの最も苛立たしい部分は、クラッシュが発生したスタック (nginx、Phusion Passenger、Ruby 1.9 パッチ レベル 243、Rails 2.3.4) のどこにログがないか、追跡できないことでした。nginx エラー ログ、Rails ログ、または見つけた場所には何も表示されませんでした。nginx、パッセンジャー、Ruby の更新されたバージョン (ステージングよりも高いパッチ レベルですが、まだ 1.9) を使用して運用サーバーを実行していたので、実行可能ファイルとサポートのすべてを転送するところまで行って、一度に各コンポーネントを 1 つずつ元に戻し始めました。ファイル (基本的には /usr/local にインストールしたものすべて) を本番マシンに転送しても無駄です。マシンをワイプしてすべてのステップを再試行しようとしたちょうどその時、誰かが本番マシンを「ステージング」環境に切り替えることを提案しました。. . 魔法のように、問題は解決しました!

何がエラーを引き起こしたのかを知りたくて、Rails コア、独自のコード、およびすべてのプラグインをくまなく調べて、本番環境でこのような大規模なハング/クラッシュを引き起こす可能性があるものについての手がかりを探し始めました。再び役に立たない。

私が見つけた唯一の手がかりは、行動でした。アプリ(レールアプリが実際に提供するページの1つ)を「オン」でテストすると、リクエストを送信してアプリをクラッシュさせ、頻繁に更新(通常は3〜4回)した後、 Nginx のログに記録され、最終的にアプリはリクエストの処理を再開します。エラーは次のとおりです。

    フェールセーフ応答中のエラー: 互換性のない文字エンコーディング: UTF-8 および ASCII-8BIT
    2009/10/09 17:52:40 [エラー] 8691#0: *88 アップストリームは、アップストリームからの応答ヘッダーの読み取り中に接続を途中で閉じました。クライアント: *my ip address*、サーバー: myapp.mydomain.com、リクエスト: "GET /api/sections/4/edit HTTP/1.1"、アップストリーム: "passenger://unix:/tmp/passenger.8677/master/helper_server.sock:"、ホスト: "myapp.mydomain.com"
    *** アプリケーションで例外 NoMethodError (nil:NilClass の未定義メソッド「each」) (プロセス 8703): /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger から/rack/request_handler.rb:95:`process_request' 内
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_request_handler.rb:206:`main_loop'内
    /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/railz/application_spawner.rb:376 から:「start_request_handler」内
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/railz/application_spawner.rb:334:in `handle_spawn_application 内のブロック'
    /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/utils.rb:182: から `safe_fork' に
    /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/railz/application_spawner.rb:332 から:`handle_spawn_application' 内
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:351: in `main_loop'
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:195: in `start_synchronously'
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:162: in `start'
    /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/railz/application_spawner.rb:213 から:「start」で
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:261:in `ブロック (2 レベル) in spawn_rails_application'
    /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server_collection.rb:126 から:`lookup_or_add' で
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:255:in `ブロック in spawn_rails_application'
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server_collection.rb:80:in `block in synchronize'
    from :8:in `同期'
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server_collection.rb:79: in `synchronize'
    /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:254 から:「spawn_rails_application」内
    /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:153 から:「spawn_application」内
    /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:286 から:`handle_spawn_application' 内
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:351: in `main_loop'
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:195: in `start_synchronously'
    from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/bin/passenger-spawn-server:61:in `'

通常、文字コードのエラーが発生した場合、最初に ruby​​ 1.9 に取り掛かります。. . ただし、私のテストからわかるように、両方のマシンで同じバージョンでした!

結局のところ、私は疑問に思っているのでしょう。. . 何が起こっているのか誰にも考えがありますか?当分の間、アプリをステージングで実行できることは明らかですが、対処しなければならないさらに深い問題が見つかったのではないかと心配しています。これが起こっている場所を探すべき次の場所についてのアイデアはありますか?

セットアップ: Mac OS X Server: 10.6.1、
Rails 2.3.4、
Ruby 1.9p243、
Nginx 0.8.17、
Passenger 2.2.5

必要な Gem :
environment.rb
デーモン
rmagick
test.rb
rspec
rspec-rails
factory-girl
rack-test

インストールされているプラ​​グイン:
act-as-dag (有向非巡回グラフを作成するためのアクティブ レコード プラグイン)
daemon_generator
globalize2
no-peeping-toms (テスト用) think
-sphinx


更新 (khell への応答):

config.whiny_nils = true を実稼働環境に追加しようとしましたが、それでもクラッシュが発生します。

また、ステージング サーバーに戻り、環境を "Production" に設定しました。. .同じクラッシュ!

「大きな」リクエストボディの意味を明確にしました。アプリケーションを一貫してクラッシュさせる POST/PUT の 1 つは、約 20,000 文字 (json) でした。API は小さな PUTS/POSTS で 1 日中一貫して使用され、稼働したままですが、これらの大きなリクエストが行われたときにのみクラッシュ/ハングしたため、2 つが接続されていると想定しました。

Rack/Ruby 1.9に関する限り。Rack と 1.9 に関する情報が大量にあるため、Rack gem を git リポジトリの最新のものにアップグレードしました (これにより、1.9 の問題の一部が修正されたと思われます)。rewindable_input、ruby 1.9 などに関するかなりの困難について読んだことがありますが、他の 1.9 アプリで経験した rewindable_input エラーが発生しなかったため、これは別の問題であると想定しました。また、Rails 環境を変更して問題が解決したときに Rack を除外しました (Rack のソース コードを検索したところ、エラーの原因となる環境固有のメソッドはないようでした)。

お役に立てれば!


pauliephonic に応答して UPDATE

rails のログにメッセージがまったく記録されていません (これにより、Web スタックで問題をしばらく検索するようになりました)。クラッシュ/ハングが発生しているという私の手がかりは、一度大きなリクエストが行われると、アプリケーションはリクエストごとに 500 エラーしか返さないことですが、これらの 500 エラーは Rails ログには表示されません。

データベース構成は同じです(mysqlクラスターを使用していたため、文字通り同一でしたが、現在はローカルのmysqlデータベースを使用していますが、使用するデータベースに関係なくエラーが発生することを確認しています)

複数のバイト/ユニコードに関する限り。. . 私たちは国際化されたアプリで作業しています。. . しかし、レールが本番環境とその他の間でユニコードの変更を処理する方法は正しくないと思いますか? 上で述べたように、これはPOSTまたはで発生しましたPUT。デバッグ中にテストする方法は、大規模で大きくネストされたモデルの 1 つの同じ編集ページに移動し、それを「保存」しようとすることでした。これにより、本番環境ではアプリがクラッシュしますが、ステージングではアプリがクラッシュしません。同じ文字、同じコンテンツ、同じボタン、同じ動作をテストするたびに. . . 環境によって異なる反応。コショウさえできなかったputs私のコードのいたるところにステートメントがありました。これは、リクエストが Rails アプリケーションに到達していないように見えたためです。RailsログまたはNginxエラーログにエラーメッセージが表示されませんでした(複数の更新で投稿したものを保存してください)。

4

4 に答える 4

0

問題がnginx/passengerに固有のものであるかどうかを確認して、Apache/passengerで本番環境でアプリを実行しようとします

于 2009-10-20T03:42:24.640 に答える
0

見たところ、そのエラーは Ruby がエンコーディングにうるさいということです。UTF-8 と見なされる文字列があり、それを raw バイトとして扱っています。おそらく正しく処理されています。問題のある文字列を特定して呼び出す必要がありますbuggy_string.force_encoding(Encoding::ASCII_8BIT)。しかし、その文字列でどのコードが動作しているか、またはそれが本番環境でのみ発生する理由を知っていれば地獄です。問題が実際に Passenger の腸の奥深くにあることを発見しても驚かないでしょう。

ステージングと本番の違いについてですが、バイト列として動かすべきものを文字列として扱っているのはほぼ間違いない問題です。実稼働環境でのみ発生するコード (キャッシュなど) が大量にあり、そのコードのいずれかがこれを行う場合、それが問題です。

そのwhiny_nilsことはおそらく無関係です。

于 2009-10-19T23:14:27.800 に答える