【Rails】Herokuで月一回のバッチ処理ができるのか

Heroku

みなさんこんにちは!tekute-kuです。

今回はHerokuで月一回のバッチ処理を行う方法を紹介していきたいと思います!

記事を書いた目的

定期のバッチ処理を設定し開発環境では実行できたものの(whenever gemを使用)、本番環境であるHerokuでは使用できなかったのでHeroku上でのバッチ処理の方法を調べてみました。

Heroku上でバッチ処理をしたいけどやり方がわからない場合の参考になれば幸いです。

タスクの定義

HerokuではHeroku Suchedulerを使ってバッチ処理をしていきますので、Schedulerで実行したいタスク定義します。

rails g task タスク名

このコマンドでタスクを記載するファイルを作成します。

今回、私の場合はメールを月一回定期配信したいのでタスク名は「mail_every_month」としました。

rails g task mail_every_month

実行結果

Running via Spring preloader in process 46812
      create  lib/tasks/mail_every_month.rake

これで lib/tasks に mail_every_month.rake というrakeファイルが作成されました。

このrakeファイルの中にタスクを書き込んでいきますが最初はまだ以下のとおりのことしか記載されていません。

lib/tasks/mail_every_month.rake

namespace :mail_every_month do
end

ここにタスクを書き込みます。

私の場合はcustomers全員にメールを配信したいのでCustomerMailerを呼び出しています。

#名前空間
namespace :mail_every_month do
  # タスクの説明
  desc "customersに一ヶ月に1回メールを配信する"
  # タスクの名前
  task remind_mail: :environment do
    customers = Customers.all
    customers.each do |customer|
      CustomerMailer.remind_mail(customer).deliver
    end
  end
end

これでタスクに反映されたかどうかをコマンドで確認します。

bundle exec rake -T

ちなみにこちらは以下のコマンドでも問題ありません。

bundle exec rails -T

Rails5以降はRakeコマンドはrailsコマンドに統合されたのでどちらでも構いません。

実行結果

rake about                              # List versions of all Rails frameworks and the environment
rake active_storage:install             # Copy over the migration needed to the application
.
.
.
rake mail_every_month:remind_mail       # customersに一ヶ月に1回メールを配信する
.
.
.
rake yarn:install                       # Install all JavaScript dependencies as specified via Yarn

ここで先ほど設定したタスクが表示されていればOKです。

Herokuのアドオンをインストール

HerokuのSuchedulerを使うにはアドオンをインストールしなければいけません。

以下のコマンドによりアドオンをインストールします。

heroku addons:add scheduler:standard

実行結果

›   Warning: heroku update available from 7.59.4 to 7.64.0.
Creating scheduler:standard on ⬢ auto-sending-system... free
To manage scheduled jobs run:
heroku addons:open scheduler
Created scheduler-tapered-41040
Use heroku addons:docs scheduler to view documentation

これでSchedulerのアドオンがインストールされました。

Schedulerの設定

続いて、先ほどlib/tasks/mail_every_month.rakeに定義したタスクを登録するため以下のコマンドでHeroku Schedulerを開きます。

heroku addons:open scheduler

そうすると下のような画面が開かれますのでCreate jobをクリックします。

 

そうすると以下の画面が出てきます。

にはバッチ処理の実行時間が選択できます。選択肢は

「Every 10minutes」 10分毎に実行

「Every hour at :〇〇」 毎時〇〇分に実行

「Every day at 〇〇:〇〇 AM・PM UTC」毎日協定世界時の午前・午後〇〇時〇〇分に実行

の3つしかなく毎月1回実行の選択肢はありません

そのため、後でのRun Commandのコマンドで毎月1回実行させるようなコマンドを入力します。

ここではに「Every day at 」を選択し、処理を実行したい時間を設定します。ちなみにSchedulerの時間設定はUTC(協定世界時)なのでJST(日本標準時)にするにはUTCにプラス9時間をするようにします。

協定世界時 (UTC) と 日本標準時 (JST) の比較対照 & 変換

今回私の場合は日本時間の午前7時に実行したいので、マイナス9時間した「Everyday at 10:00PM UTC」とします。

Everyday at 10:00PM UTC

続いてには月一回にrakeタスクを実行するコマンドを入力します。

[ $(date +%d) = 20 ] && rake mail_every_month:remind_mail

このコマンドは毎月20日にrakeタスクを実行することが記述されています。

なおこれはLinuxコマンドになります。

 

入力したら最後にsave jobをクリックします。

すると以下のような画面が出てきてジョブが追加されたことが確認できます。

これで毎月21日の午前7時にrakeタスクが実行されるようになりました。

まとめ

  • Herokuでも月1回のバッチ処理は可能である
  • lib/tasksにrakeタスクを作成して実行させる
  • Heroku Schedulerというアドオンをインストールしなければできない
  • Heroku Schedulerは協定世界時を採用しているため、日本照準時(日本時間)に直す必要がある

 

参考:

Herokuで月一回のバッチ処理を実装する方法

Heroku Scheduler

heroku schedulerの使い方(Rails,sinatra)

コメント