AWS Lambda でHeroku の無料枠でサーバーが寝ないようにする(2018年版)
先日、ラップボットのDJ マルコをご紹介しました。
DJ マルコはheroku にデプロイしてるんですが、下記のような問題がありました。
- フロント(Rails on Heroku) とバック(Flask on Heroku) の2台構成になっている
- heroku サーバーは30分リクエストが無いと寝てしまうので、ただでさえ起動が遅いのに加えて、フロントがバックの起動を待っている間にタイムアウトして、必ず1リクエスト目がエラーになってしまっていた
そのため、定期的にping して起こしておきたいと思いました。 少し調べたところ、下記の記事が見つかりました。
UptimeRobot は設定が非常に簡単で良かったのですが、監視の時間帯を設定することができないようでした。
そうすると、24時間 2つのdyno が動き続けることになり、合計で24 * 2 * 30 = 1440 時間となってしまい、無料枠の1000時間を超えてしまう問題がありました。
他の案も、dyno 時間を消費してしまうので、今回の要件には合わなそうでした。
そこで、AWS Lambda でhealth check だけするfunction を作って、AWS Watch Rules で昼間だけ動くようにしました
- lambda_handler.py
from urllib.request import urlopen from datetime import datetime, timedelta def validate(expected, res): return expected in str(res) def lambda_handler(event, context): try: if not validate(event['expected'], urlopen(event['site']).read()): raise Exception('Validation failed') except: print('Check failed!') raise else: print('Check passed!') return 'OK' finally: print('Check complete at {}'.format(str(datetime.utcnow() + timedelta(hours=9))))
ping 対象のURL と、チェック文言を起動時の引数で与えるようにしているので、他のURL でも流用が可能です。
今回は
{"site": "https://rhyme-bot.herokuapp.com/health/marco", "expected": "OK"}
これで、9時〜24時の15時間だけ起こしておくことになったので、15 * 2 * 30 = 900 時間で、無料枠(1000時間) に無事収まります。やったね!