
Herokuの無料のdynoを使っている場合、現時点のルールでは30分でスリープしてしまいます。スリープしてしまうと、アクセスした時点で起動するのでサイトの表示がかなり遅くなってしまいます。今回は、このスリープを回避して、無料dynoを24時間稼働させる方法を紹介します。
見出し
はじめに
Herokuの無料dynoのルールは割りとコロコロ変わっているのですが、現時点では無料dyno全て合わせて月1000時間までが無料で使え(会員登録すると月550時間が与えられ、クレジットカード登録すると月450時間が追加される)、無料dyno(プロセスタイプがwebの場合)はアクセスがなければ30分でスリープする仕様になっています。
この30分でスリープする仕様ですが、スケジューラを使って定期的にcurlやpingなどで対象のアプリにアクセスをすることで回避できます。この方法を使えば、1dynoまでなら無料で24時間稼働させることが可能です。
Herokuのdynoスリープ回避策①外部サービスを使う
これが無料で最も簡単な方法でしょう。いろいろ設定するのが面倒であればこれがおすすめです。
外部のモニタリングサービスであるUptimeRobotを使う方法です。
まずはUptimeRobotのアカウントを作り、ログインします。
「Add New」Monitor」からモニターを追加します。
「HTTP(s)」を選択します。
名前は分かりやすいものを付けて、URLにHerokuアプリのURLを入力します。Monitor Intervalはデフォルトで5分間隔なので、そのままにしておきます。入力が終わったら「Create Monitor」をクリックします。
これで、Herokuアプリが5分毎にチェックされるので、スリープを回避できます。モニタリングの結果は以下のように表示されます。
無料で十分ですね。
Herokuのdynoスリープ回避策②Heroku Schedulerを使う
すでに何かしらのアプリケーションをHerokuにデプロイ済みであり、Herokuにクレジットカード情報の登録がしてあることを前提に進めます。仮にそのdynoをyour-herokuapp-xxxxxとします。
アドオンをインストールする
Schedulerという無料のアドオンをインストールします。
$ heroku addons:create scheduler:standard
Creating scheduler:standard on ⬢ your-herokuapp-xxxxx... free
This add-on consumes dyno hours, which could impact your monthly bill. To learn more:
http://devcenter.heroku.com/addons_with_dyno_hour_usage
To manage scheduled jobs run:
heroku addons:open scheduler
Created scheduler-tapered-10112
Use heroku addons:docs scheduler to view documentation
ジョブを設定する
スケジューラにジョブを設定します。ブラウザからもできますが、コマンドで開きましょう。
$ heroku addons:open scheduler
ブラウザが開いたら「Add new job」をクリックします。
DYNO SIZEはもちろん「Free」で、定期ジョブの実行間隔FREQUENCYは「Every 10 minutes」を選択します。これは10分間隔でジョブを実行することを意味するので、30間隔でアクセスが無ければスリープしてしまうというHerokuの仕様を回避できます。
ジョブの内容はGETすればよいので、「curl https://your-herokuapp-xxxxx.herokuapp.com/」でよいでしょう。ジョブの内容を入力したら、「Save」をクリックします。
ジョブの登録が完了しました。
これでスケジューラの設定は完了です。試しに30分放置してサイトを見に行って下さい。スリープせずに稼働していれば成功です。
Heroku Scheduler利用時の問題点
Heroku Schedulerは確実に実行されるものではなく、タスクがスキップされたり、2度同時に実行されたりといった問題が稀に発生することが知られています。詳しくは公式サイトを参照して下さい。
加えて、予期しない課金リスクもあります。Heroku Schedulerのアドオン自体は無料ですが、スケジューラがタスクを実行す時にOne-Off dynoを立ち上げています。これは時間課金のdynoです。アドオンの利用の条件がクレジットカードの登録である理由はここにあります。このOne-Off dynoの起動時間も無料枠の時間に含まれるので、無料枠が超過した場合課金されます。この課金リスクに関しては、One-Off dyno全てに言えることなので、意識した方が良いでしょう。
この方法はメジャーな方法ですが、上記の問題があるため個人的にはおすすめしません。
Herokuのdynoスリープ回避策③NewRelicを使う
すでに何かしらのアプリケーションをHerokuにデプロイ済みであり、Herokuにクレジットカード情報の登録がしてあることを前提に進めます。仮にそのdynoをyour-herokuapp-xxxxxとします。
NewRelicのアカウントを作る
NewRelicのサイトに行ってアカウントを作ります。電話番号も必要なので面倒ですが。
アドオンをインストールする
NewRelic用の無料のアドオンをインストールします。
$ heroku addons:create newrelic:wayne
Creating newrelic:wayne on ⬢ your-herokuapp-xxxxx... free
Created newrelic-transparent-xxxxx as NEW_RELIC_LICENSE_KEY, NEW_RELIC_LOG
Use heroku addons:docs newrelic to view documentation
NewRelicを設定する
$ heroku addons:open newrelic
モニタータイプに「ping」を選択して、対象のHerokuアプリのURLを入れれて、15分毎にpingされるようにすればOKです。
Herokuのdynoスリープ回避策④自前スケジューラーの実装
最後ですが、Herokuのdynoとしてスケジューラを実装します。この方法はdynoが増えるので普通に起動しておくと無料枠を超えてお金かかります。なので、この方法を利用する場合は、スケジューラだけのdynoとして起動させずに、例えばメインのアプリのソースコードとして含めてしまって一つのdynoにまとめてしまうなどの工夫が必要になります。つまり、メリットはほとんどないので、おまけ程度に考えて下さい。
すでに何かしらのDocker化されているアプリケーションをHerokuにデプロイ済みである前提で進めます。仮にそのdynoをyour-herokuapp-xxxxxとします。
必要なファイルの準備
まずは、必要なファイルを作ります。
$ cd your-herokuapp
$ touch clock.js
$ touch Dockerfile.clock
スケジューラー自体はNodeJSで実装しますが、そのスケジューラーはDockerコンテナとして実装するので、メインのアプリが何の言語で書かれていても問題ありません。
スケジューラーをNodejSで実装
clock.jsを実装します。
const http = require('http');
const URL = 'http://your-herokuapp-xxxxx.herokuapp.com'; // 独自ドメインでもOK
const INTERVAL_MSEC = 10 * 60 * 1000; // 10分毎(30分未満ならOK)
setInterval(() => {
http
.get(URL, res => {
console.log(res, URL);
})
.on('error', err => {
console.log(err, URL);
});
}, INTERVAL_MSEC);
あえてNodeJSに最初から含まれているhttpモジュールを利用しています。モジュールの入れるほどの内容ではないので。
Dockerfileを書く
Dockerfile.clockは以下になります。
FROM node:9.11.1-alpine
RUN mkdir /app
WORKDIR /app
COPY clock.js clock.js
CMD node clock.js
Dockerfileのファイル名に拡張子としてclockが付いていますが、これはHerokuにプロセスタイプを知らせるためのHerokuの仕様です。clockでなくても、好きな名前を使って下さい。
Herokuに自前スケジューラーをデプロイする
それでは完成した自前のスケジューラーをHerokuにデプロイしましょう。
$ heroku container:login
$ heroku container:push clock --recursive
$ heroku ps:scale clock=1
「heroku container:push」に「--recursive」を指定することでDockerfileの拡張子(今回はclock)をプロセスタイプと認識してデプロイしてくれます。また、デプロイしただけでは起動しないので、「heroku ps:scale clock=1」で起動しています。停止したい場合は「heroku ps:scale clock=0」とすればOKです。
※追記※ Container RegistryにDockerイメージをPushした後に、Releaseコマンドが必要になりました。こちらの記事を参考にして下さい。
Docker化されていない場合
Docker化されていないアプリケーションの場合は、Dockerfileは不要なのでもっと簡単です。その場合は、以下のようなProcfileファイルを用意して、上記のclock.jsをherokuに通常の方法でpushすれば良いでしょう。
web: node your-app.js
clock: node clock.js
詳しくは公式サイトを参照して下さい。
最後に
いかがでしたか?これで無料dynoを24時間稼働させることができるようになったと思います。個人的にはもう少し無料dynoの稼働時間を延ばすか、Hobbyの値段を下げてほしいのですが、まあ、高く感じてきたらDigitalOceanあたりにに乗り換えるのもよいかもしれませんね。では。


コメントを残す