ElasticBeanstalkのワーカー環境で定期バッチ処理を動かしてみた

ElasticBeanstalkのワーカー環境で定期バッチ処理を動かしてみた:


はじめに

適当になりがちだけど、扱いに悩むことも多い定期バッチ処理。

ちょっとしたタスクならWebサーバ内のcronで呼び出しちゃったりするけど、コンテナ+複数インスタンスの環境で、ちょっとスマートな感じにしたい。

定番はSQS+Lambdaかと思いますが、既にWebアプリ上に機能があったりする場合、ElastiBeanstalk(以下EB)のワーカー環境が便利です!



image.png


こんな仕組みらしい。

ややこしいキューの管理はEBにお任せできちゃいます。

公式ドキュメント:AWS Elastic Beanstalk ワーカー環境

EB環境の作り方等はドキュメントをご参考ください。
AWS Elastic Beanstalk 環境を作成する


APIを用意する

ワーカー環境内のSqsdからHTTP POSTで呼び出されます。

なので、通常のWeb APIとして処理を実装すればOK。

かんたんですね!

とはいえ、同じアプリケーションをWebに公開している場合は外部からアクセスされたくないので、IP制限的なものはかけておきましょう。

こんな感じで、ネットワーク外からのアクセスをブロック。

if (request.remote_ip =~ /(^10\.|^172\.(1[6-9]|2[0-9]|3[0-1])\.|^192\.168\.)/).nil? 
  redirect_to root_path 
end 


cron.yamlを用意する

タスクの名前と↑で用意したAPIのURL、実行スケジュールを定義したcron.yamlを作ります。

scheduleはcronの形式そのまんま。

cron.yaml
version: 1 
cron: 
 - name: "batch_task_1" 
   url: "/batch/task_1" 
   schedule: "* *1 * * *" 
 - name: "batchtask_2" 
   url: "/batch/task_2" 
   schedule: "* */12 * * *" 
cron.yamlに記述したschedule通りにEBがSQSのキューにメッセージを追加し、それを受け取ったEBのSqsdがHTTP POSTでURLを呼び出されます。

という仕組みのようです。

あとは、ソースバンドルに含めてzip形式にしてアップすれば


おまけ(ハマりポイントその1)
cron.yamlはECRのイメージ内に置いてもダメ

今回の環境はMulti ContainerなEB環境で、Dockerrun.aws.jsonのみをアップロードし、ECRからイメージを持ってきてデプロイしています。

試しにcron.yamlをプロジェクトルートに置いてECRにプッシュしてみたのですが、これではスケジュールは登録されず。
Dockerrun.aws.jsonと一緒にzip化したものをアップしてデプロイ時のソースバンドルとして指定したところ、無事登録できました。

問題なく登録できた場合は、EBダッシュボードのイベント内に

Successfully loaded 2 scheduled tasks from cron.yaml.

のように表示されるはずなので、これを確認しましょう。


おまけ(ハマりポイントその2)
Lhaplusで圧縮したらうまく読み込まれない

これは本当に原因が謎。

ワーカー環境云々というより、EBの仕様かな?

ドキュメントに書いてある通り、送る→圧縮(zip形式)フォルダー(Window環境)としたら問題なくアップできました。


おまけ(ハマりポイントその3)
なぜか5分に1度呼び出される

APIが
204 No Content

を返しているのが原因で、デッドレターキューにメッセージがいってた。。

API処理の最後に以下を追加して解決。(Rails)

render body: nil 

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)