いっきのblog

技術とか色々

LaravelのバッチをDiddagで運用したら少し幸せになった話

どうも、くずきです。
弊社の本番環境のバッチはスピード優先で作ったのもあって、処理ごとに分けてはいるものの連携を取ろうとすると以下のことをしなきゃいけない。

  1. 手動で1つ目のバッチを回す
  2. 1つ目が終わったら次のを回す
  3. それが終わったら次を回す・・・

コマンド一つ叩くだけなので、大きな作業は発生しないにしろバッチとバッチの間の無駄な時間やどこまでバッチが終わって、どれくらいかかって、こけた場合はどこでこけたのか・・など色々問題があった。

そこで、Laravelのタスクスケジュール使う手もあったんだけどフローの可視化やリトライ処理を簡単にやりたいと思っていたので、前から良さげだなとおもっていたDigdagを導入してみました。

Digdagとは

あらゆる手動作業を自動化しよう!!というコンセプトで作られたワークフローエンジンです。

github.com

細かい説明は、作成者でもある古橋さんの資料を参考にしましょう。。。

www.slideshare.net

とりあえずいいところとしては、

  1. ymlっぽいやつで簡単にかける
  2. 高可用性な構成にできる
  3. 分散処理できる
  4. テスト段階ながら、UI(可視化など)が提供されている

かなと思う。

既存バッチの把握

まずは、既存バッチを把握する。
Step1 ~ Step4までバッチが分かれており、簡単な図を混ぜながら説明。

  • Step1: 処理したいデータをキューに入れる  
    • sshでログインしてバッチを叩く
    • 3時間前後で終わる

f:id:kzkohashi:20171203230211p:plain

  • Step2: キューに入ってるデータを処理する
    • バックグラウンドで常に動いてるため、特にすることはない
    • 外部のデータに依存するので、長いと数日かかる

f:id:kzkohashi:20171203230250p:plain

  • Step3&4: sshでログイン後Step2のデータを処理する
    • sshでログインしてバッチを叩く
    • 8時間前後で終わる

f:id:kzkohashi:20171203230258p:plain

Digdagへの移行

Digdagのインストールについては今回は省く。
ここに書いてある通りやればすぐ使えると思う。

Getting started — Digdag 0.9.5 documentation

一応載せとく。

$ curl -o ~/bin/digdag --create-dirs -L "https://dl.digdag.io/digdag-latest"
$ chmod +x ~/bin/digdag
$ echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc

ちなみに、batch server 1 にインストールしてある。

次にPHPの起動については特に用意はされていないので>shコマンドを使う。

sh>: Shell scripts — Digdag 0.9.5 documentation

このままだとStep2の処理はバックグラウンドで動いてるため、Step3へのフックがない。
そこで、Step2が終わっているかの処理(キューにデータがあるかなど)を行うバッチを追加で書いた。

Step2_task_check

    public function handle()
    {

        $this->line(Carbon::now() . ': start step2_task_check');

        for(;;) {
        
          if (キューの中身があるか)
          {
            // 0を返す
            return config('command.exit_code.SUCCESS');
          }
          sleep(60);
        }


        $this->line(Carbon::now() . ': end step2_task_check');
        
        // 1を返す
        return config('command.exit_code.ERROR');

    }

0 or 1を返すようにすれば、Digdag側で成功か否かを判断してくれる。
ここまで準備したらあとはymlっぽいやつをかけば終わり。

BatchFlow

timezone: UTC

+setup:
  echo>: start ${session_time}

+disp_current_date:
  echo>: ${moment(session_time).utc().format('YYYY-MM-DD HH:mm:ss Z')}

+step1:
  sh>: php /var/www/app/artisan app:step1

+step2:
  sh>: php /var/www/app/artisan app:step2_check

+step3:
  sh>: php /var/www/app/artisan app:step3

+step4:
  sh>: php /var/www/app/artisan app:step4

+teardown:
  echo>: finish ${session_time}

ほぼほぼチュートリアルのままで完成。
特にエラー処理とかDigdagの売りなことは特にしてないんだけど、まずは少し幸せになるという目標だったので自分的にはこれだけでもかなり楽になったし、細かくバッチを作れば組み合わせも楽なので嬉しい。

Digdagに処理をpushする

batch server 1Digdag Serverは起動してある。

digdag push batch_flow

こんな風にpushする。

f:id:kzkohashi:20171203230329p:plain

Digdag UI で起動&確認

Digdag UIDigdagを起動したら勝手に立ち上がっている。
ただ、外向けのポート開けてないっぽいため65432sshのトンネル作って確認する。

ssh -L 8000:localhost:65432 ec2-user@ip -i "~/.ssh/xxx.pem"

その後、pushされた処理があるため、それを起動すれば完了。

終わりに

Digdagの色々良いところは使いきれてないけど、「手動を自動化する」というミッションに関してはすごく簡単にできたので良いと思います。
次くらいまでには、障害に強い構成にしたり、バッチのリラン、Slackへの通知などやる予定。