2011-12-14 5 views
7

私はGoogle経由で情報を見つけることはあまりありませんでしたが、多分誰かが似たような問題を抱えていました。Herokuの遅いpostgresクエリがラックタイムアウトで中断されていません

私たちは、Postgres DBを使用してHeroku上で動作するレールアプリを持っています。私たちは特に低速のクエリを持っていますが(質問は修正しています)、この問題をデバッグする過程で、私たちのラックタイムアウトの宝石は15秒で要求を殺していないことがわかりました。私はsleep(50)を挿入してサイドテストを行いましたが、そのような場合には十分なラックタイムアウトが正しく機能しています。

ログの編集済みのコピーで、数分後にラックタイム(時間が稼働しています)が発生していて、30秒後にH12 Request Timeoutが表示されます。

2011-12-14T21:15:16+00:00 app[web.2]: Started GET "/search?utf8=%E2%9C%93&terms=foo" for 173.164.186.205 at Wed Dec 14 13:15:16 -0800 2011 
    2011-12-14T21:15:16+00:00 app[web.2]: search query elapsed time => [0.000365018844604492] 
    2011-12-14T21:15:46+00:00 heroku[router]: Error H12 (Request timeout) -> GET /search dyno=web.2 queue= wait= service=30000ms status=503 bytes=0 
    2011-12-14T21:18:47+00:00 app[postgres]: [6-1] [removed] [COBALT] LOG: duration: 211241.725 ms statement: SELECT [truncated] 
    2011-12-14T21:18:47+00:00 app[web.2]: 
    2011-12-14T21:18:47+00:00 app[web.2]: ActionView::Template::Error (Timeout::Error: time's up!: SELECT [truncated]): 

ラックタイムアウトを実施する理由と方法についての洞察はありますか?

答えて

4

はい、ここでは私がゾンビダイノと呼ぶものがあります。 30秒のタイムアウトは、Dynoの上にあるルーティングメッシュで発生します。理論的には、あなたのdynoは数時間稼動できますが、ルーティングメッシュから直接30秒後にエラーが表示されます。

So.何が起こっていることはこれです:

  1. あなたの要求は、ルーティングメッシュが、それは誤りだ返す21:15:4621:15:16
  2. で行われるが、あなたのダイノはまだ21:18:47あなたの要求が終了で
  3. を処理しています。ラックで起こっていただきました!については

::タイムアウトして、実行時間の長いクエリは、それ多分あなたがラックとして使用してPGの宝石へのダウン::タイムアウトが正しく機能するスレッドに依存しています。これは、データベースが復帰する瞬間にタイムアウトが発生する理由を説明しています。ゾンビdynos上

さらに詳しい情報:http://neilmiddleton.com/avoiding-zombie-dynos-with-heroku/

+0

お返事ありがとうございます。私が探しているのは、ラックタイムアウトを強制的に解除してリクエストを切断する方法に関する洞察です。私たちはherokuを使用しており、pg_gemを指定していません、herokuはします。バージョン9.0.6の非共有データベースを使用しています。 – sorens

+0

残念ながら、Rack Timeoutは実行中のクエリを強制終了できません。あなたのアプリケーションは、スラッグコンパイルプロセスによって注入されたように、Heroku上のpg gemを使用します。 –

1

はpostgres 9.2(より良いタイムアウトシステムを持っている)が出てくるまでは、ラックタイムアウト宝石との簡単な解決策はありません - 文との間にpostgresの接続の中断のためにのみチェックをしたがって、ラックタイムアウトはこの点で幾分制限される。その手は結ばれています...あなたがスーパーユーザーにアクセスしてポストグルにアクセスした場合、いくつかの設定を試すことができるかもしれませんが、あなたがヒーローにいるので、それは選択肢ではありません。

データベースコールを最適化してください(すべてのインデックスが存在することを確認してください)。または、この特定の問題のために単一のステートメントを小さな塊に分割してください(これは直感的ではないようです)。