こんにちは、皆さん!
Herokuにデプロイしたウェブサイトを開いて、一定の時間が経ってからもう一度アクセスすると、読み込みにすごい時間がかかった経験ありますよね?
この状態をスリープといいます(コンピュータをスリープさせたときのように)。
今回はそんなイライラするスリープ状態を無料で解決しちゃう方法をご紹介しようと思います!


トピック


動機

まず、僕自身がなぜこのようなことをしようと思ったのかを解説しようと思います。

この裏技を組み込んだ頃にツイッターにツイートをスケジュールできるウェブアプリ(リンク)を制作していました。それで、ユーザーが日にちを指定してスケジュールを完了すると、ウェブサイトの裏で処理をしているワーカーが時間になった時にツイートをするためツイッターに対してAPIリクエストを送るという仕組みになっているのです。
だが、もし、そのままだと、Herokuアプリがスリープ状態になってしまい、ワーカーが必要な時にスリープしていて、タスクをこなせない状態になってしまうのです。
というわけで、Herokuがスリープ状態に入るのを防ぐ必要が出てきたのがこの裏技にたどり着いたきっかけなのです。


どうしてスリープするのか?

まず、そもそもなぜHerokuアプリは自動でスリープしちゃうのでしょうか?

それはHerokuが30分間そのウェブサイトにアクセスがないと、そのウェブサイトをスリープ状態にしてしまうからです。これはHeroku側のサーバーでウェブサイトをホストするのにスペースがかかるからで、なるべくリソースを効率よく使うために皆に分配するためです。

具体的に言うと、一つのウェブサイトをホストしていたスペースを30分後に空いたら、他のウェブサイト用に使うことで、一つのスペースでいくつものウェブサイトをホストできちゃうっていうわけですね。


一般的な解決方法

とはいえ、そんな不便だったらどの会社もHerokuを使わなくなってしまいます。なので、Herokuは一般的な会社と同じようにお金を払ってくれたものにはしっかりとスペースを確保してくれるシステムになっているのです。
一番安いHobbyプランで行くと、一つのアプリで1か月7ドルかかります。この金額を払っていれば、Heroku側であなたのウェブサイト専用にスペースを確保してくれて、ずっと使えるようにしてくれるからウェブサイトがスリープしなくなるのです。
これが一般的で簡単な解決方法です(節約は楽ではないので笑)。
だが、賢い人たちは次のような無料でこの問題を解決する方法を思いついてしまうのですね。


無料の解決方法法

そもそもHerokuのウェブサイトがスリープ状態になってしまうのは30分間アクセスがないからです。つまり、簡単な話、30分に一回ウェブサイトにアクセスすればいいのです。
しかし、寝ずに30分ごとに一回ウェブサイトをアクセスするのは無理な話ですよね。なので、「このタスクをプログラミングしちゃえ!」っていうのが斬新だが画期的な打開策なのです。つまり、今必要なのは「少なくとも30分に一回ウェブサイトにアクセスするプログラム」ということになります。でも、いったいどうやってやるのでしょうか?

まずは、後半部分の「ウェブサイトにアクセスする」を処理していきましょう。ウェブサイトにアクセスするということはHTTPのGETリクエストを行うということに等しいです。なので、Pythonで書くと、下記のような簡単なコードになります。

import requests

r = requests.get(url="https://example.herokuapp.com") 

これは非常に簡単なコードで、https://example.herokuapp.comのURLのウェブサイトにGETリクエストを送り、そのレスポンスをr変数に保存するというものです。
このコードが入っているファイルをこの際task.pyとし、フォルダーのルートディレクトリにあると仮定しましょう。

次に残りの前半部分、「少なくとも30分に一回行う」の部分を処理していきましょう。少なくとも30分に一回なので10分に一回とかでも問題ないということです。そして、これをどうやってやるかというと、Herokuのアドオンにかなり便利なものがあり、Heroku Schedulerといいます。これはその名の通り、一定時間ごとにタスクをHerokuのアプリに実行させるというものです。このアドオンを下記のようにターミナルから追加します。

heroku addons:create scheduler:standard

そして、HerokuのウェブサイトからResourcesを選んで、Heroku Schedulerアドオンをクリック。この編集画面で右上のAdd Jobで下記のようにタスクを追加できる。

Heroku Schedulerでタスクを追加

一番上のEvery 10 minutesにより、このタスクが10分ごとに行われるように設定します。
下のコマンドのところに先ほど書いたプログラムを実行できるようなコマンドを入力すればオッケーです。ここではPythonなので、Pythonコードを実行するためのpython file_nameというコマンドでタスクを実行しています。

(Railsの例がこちらのサイトに載っています: https://coderwall.com/p/u0x3nw/avoid-heroku-idling-with-new-relic-pings

つまり、これで「10分ごとに一回ウェブサイトにアクセスするというプログラム」ができてしまったのであります。そして、30分以内に必ずウェブサイトにアクセスされるので、このサイトはスリープ状態には入らなくなるのです。なんと素晴らしいことか、プログラミング万歳!!


注意点

これだけ見ると、かなり魅力的な話です。だが、一方でこれを実行する際に気を付けてほしいこともあります。それは、もともと非課金ユーザーに与えられた、ウェブサイトがノンスリープ状態でいられる時間がクレジットカード未登録の場合、1か月550時間、登録者の場合、1000時間であることです。一日24時間×1か月30日でおよそ720時間をそのウェブサイト一つで消費してしまうのです。クレジットカードを登録してない場合は時間が足りなくなり、登録している人は少しの時間しか残せないのです。なので、同じアカウントの他のウェブサイトをホストする時間が無くなる可能性があります。

少しめんどくさくなるが、解決方法として、別のHerokuアカウントを作り、そのアカウントをある特定のスリープしてほしくないウェブサイトをホストする専用のアカウントとしてウェブサイトを運営していく方法があります。しかし、この場合、git push heroku masterする際にいちいち別々のアカウントにログインしないといけないので、くれぐれも注意してください。


まとめ

今回はHerokuのウェブサイトを無料でノンスリープのまま運営していく方法を紹介しました。
僕もここまで簡単に解決できるとは思っていなかったので、最初はすごく感動しました。いくつか注意点もあるので、そこらへんも気をつけながら、理想のウェブサイトアプリを作りましょう!
みなさんの役に立つことを願います!
では、また次回まで✌
記事更新はツイッターで告知するので、ツイッターの方でもフォローお願いします!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です