LoginSignup
0
2

More than 1 year has passed since last update.

Herokuの読み込みが遅い問題をGASで定期リクエストを送ることによって解決する

Last updated at Posted at 2021-09-11

はじめに

Herokuは簡単にデプロイできる上に無料枠があるため、多くの人が使っていると思います。
しかし30分以上アクセスがないとDyno(Herokuで利用されるLinuxコンテナ)がスリープ状態に入ってしまい、読み込みが遅くなってしまいます。
今回は自分が起きている時間帯だけ常時起動させ、就寝中はスリープ状態にさせる方法を執筆します。
ちなみに就寝中にスリープさせるのは理由があります。
後述しますが、簡単に言えばクレジットカード登録なしの無料枠内で常時起動させるには時間に制限があるからです。
また、何らかのトラブルが発生した際は自己責任でお願いします。

前提

対象者

  • Herokuにアプリケーションをデプロイ済み
  • 完全無料で使いたい
  • Herokuにクレジットカードを登録したくない
  • GASを利用できる

注意事項

多くの人はDynoのフリープランを使っていると思います。
DynoというのはHerokuで利用されるLinuxコンテナであり、皆さんはその上にアプリケーションをデプロイしているイメージです。
Herokuアカウントにつき550Dyno時間/月が備わっており、1ヶ月でDynoを550時間無料で動かすことができます。
クレジットカードを登録すれば1000Dyno時間/月まで増えます。
注意していただきたいのが、1ヶ月は24時間*31日744時間ということです。
550時間というのは約22日です。
つまり、常時起動させていると約22日しかアプリを利用できないということになります。
言い換えれば1日あたり約7時間以上スリープさせれば、550時間内に抑えることができます
これが自分が就寝中の時スリープさせる理由です。
もちろん一日7時間以上スリープ状態にできれば就寝中にこだわる必要はありません。

またこちらの記事によれば、一つのアカウントで2つの以上のアプリケーションを起動させると合算になるので注意が必要とのことです。
今回は一つのアプリで1ヶ月550時間近く利用するわけですから、同じアカウントで他にアプリをデプロイして利用することは難しいことを念頭においてください。
もし同じアカウントで他にもアプリをHerokuで利用したい場合は、スリープ時間を増やして調整してください。

仕様

  • 自分が起きている時間帯(午前10:00~深夜2:00の16時間)は30分おきにHerokuにリクエストを投げ、就寝中の8時間はリクエストを投げずスリープ状態にさせる。

Herokuにリクエストを投げるのはGASを使います。
GASにはスクリプトを定期実行させる機能があり、今回はGASの無料枠内で抑えることができます。
他にも選択肢はありましたが、

  • Heroku Schedulerで工夫する....そもそもこのアドオンを利用するにはクレジットカードの登録が必要なので却下
  • モニタリングツールで定期的にリクエストを投げる...このためだけにツールの登録をするのは気がひけるのと、GASの方が慣れているのでトリガーの設定や拡張がしやすいと思ったので却下

最終的に慣れているGASに決めました。

GASの設定

1からGASの設定を説明するのは手間なので、要所をお伝えします。
コード自体は単純です。
適当なプロジェクトを作成し、main.gsに以下を記述します。

main.gs
function fetchHeroku() {
  const isSleepingTime = checkSleepingTime();

  if(!isSleepingTime){
    const url = "あなたのherokuアプリのURL"
    UrlFetchApp.fetch(url);
  }
}

function checkSleepingTime(){
  const startSleepingTime = 2;
  const endSleepingTime = 10;
  const currentTime = new Date(); 
  const currentHours = currentTime.getHours();
  return currentHours >= startSleepingTime && currentHours < endSleepingTime
}

まず現在時刻を取得し、スリープする時間か否かでリクエストを送るか判断してます。
このURLに対応するアクションは処理が軽いものにしましょう。
ただhelloと返すようなアクションで十分です。

続いてトリガーを設定します。

トリガーの保存ボタンを押すのは現在の時刻を確認して、必ずx時0分になるのを待って設定してください。

クリックして理由を表示

このトリガーで30分おきを設定するのですが、設定した時間から30分おきになってしまいます。
今回のサンプルコードでは、10:00になったらアプリが起動して欲しいですよね。
例えば16:57にトリガーを保存したら、x時57分とx時27分に毎回実行されます。
そうすると当然ですが9:57分になった時にもスクリプトが実行されます。
この時まだスリープ状態であるため、リクエストを投げません。
次実行されるのは10:27分になるため、10:15分の段階でもスリープ状態のままになってしまいます。
これを避けるためにx時0分、あるいは1分許容してx時1分になったタイミングで保存ボタンを押してください。

1.画面左の時計マークをクリックし、トリガーを追加
2.「実行する関数を選択」でfetchHerokuを選択
3.「実行するデプロイを選択」でHeadを選択
4.「イベントのソースを選択」で時間主導型を選択
5.「時間ベースのトリガーのタイプを選択」で分ベースのタイマーを選択
6.「時間の間隔を選択(分)」で30分おきを選択
7.保存する

これで完了です!
ログを見てしっかりと機能しているか確認してください。

終わりに

これで起きている間は読み込みのストレスがなくDyno上のアプリにアクセスできると思います。
スリープ時間はHerokuにデプロイした他のアプリのことを考慮しながら適宜変えてください。
トリガーは簡単に削除できます。

GASの定期実行は本当に便利なので、是非試してください。

参考

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2