Herokuでデプロイエラーが起きた

いつものようにさくっとpushすると、サイトにアクセス出来ない。。
とりあえず、rollbackで戻しておいたが、原因を探った。

ログを見ると以下のようになっていた。

heroku/web.1:  State changed from up to starting 
app/web.1:  Going down, terminating child processes... 
heroku/web.1:  Stopping all processes with SIGTERM 
heroku/web.1:  Process exited with status 0 
heroku/web.1:  State changed from starting to crashed
heroku/web.1:  State changed from crashed to starting 
heroku/web.1:  Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch 
heroku/web.1:  Stopping process with SIGKILL 
heroku/web.1:  Process exited with status 137 

どうやら、R10 (Boot timeout)なるエラーが発生しているよう。

R10 – Boot timeout

A web process took longer than 60 seconds to bind to its assigned $PORT. When this happens, the dyno’s process is killed and the dyno is considered crashed. Crashed dynos are restarted according to the dyno manager’s restart policy.

Webプロセスは、割り当てられた$PORTにバインドするために60秒以上かかった。これが発生すると、dynoのプロセスは強制終了され、dynoがクラッシュしたと考えられている。ダウンしたdynoは、dynoマネージャの再起動ポリシーに応じて再起動されます。

This error is often caused by a process being unable to reach an external resource, such as a database, or the application doing too much work, such as parsing and evaluating numerous, large code dependencies, during startup.

このエラーは、多くの場合、データベース、または起動時に、非常に多くの、大規模なコードの依存関係を解析し、評価するようなあまりにも多くの処理を行なっているアプリケーションなどの外部リソースに到達することができないというプロセスが原因で発生します。

Common solutions are to access external resources asynchronously, so they don’t block startup, and to reduce the amount of application code or its dependencies.

一般的な解決策は非同期に外部リソースにアクセスすることなので、起動をブロックしないように、アプリケーションコードまたはその依存関係の量を低減する事です。

サポートに問い合わせることで、この60秒制限を120秒にすることもできるそう。


Heroku::Forward

R10エラーが起きる主な原因は存在しない外部リソースへのアクセスや、使用しているgemの量が増えている事が挙げられるらしい。
それを自動で整理?してくれるようなものが以下のよう。

dblock/heroku-forward · GitHub

しかしこれはRuby。今回はPHP


原因

で、テストアプリを作って全く同じ構成にして検証してみたところ、
NewRelicが重くなってしまっているようだった。
試しにそれを外すとエラーが出なくなった。


対策

NewRelicはアプリを起動し続けるためのpingとしての使用がメインだったので、
(ログなどが見られるのは嬉しかったが)
同じように定期的にpingを飛ばす方法を探してみた。

Heroku Schedulerで叩き起こす

知っておきたい!Herokuを使う上では当たり前?の16の常識 | mah365

1時間毎にcurl http://your-app-name.herokuapp.com/というコマンドを叩くように設定すれば、起き続けます。

Heroku Scheduler
アドオンを追加

$ heroku addons:add scheduler

この状態でデプロイが通るかを確認。→ OK。

Phpstrom diff

以下を追加

curl http://your-app-name.herokuapp.com/

FREQUENCY(頻度)を、Hourlyにして、save。

Phpstrom diff

これで1時間毎に指定のURLを叩いてくれる。


Dyno Hour

Herokuの料金は、1Dynoで起動時間が月750時間までは無料。
通常であれば、1日 x 24時間 x 31日 = 744時間 で、無料範囲ない。
ただし、Heroku Schedulerで実行した時間もDynoの起動時間に含まれる。

単純にURLを叩くだけ、なら大丈夫かと思うけれど、
重めのバッチ処理をスケジューラーでこまめに起動していると請求が発生する可能性があるので注意。

   このエントリーをはてなブックマークに追加