タグ別アーカイブ: node-cron

worker Dynoを利用してNode.jsバッチを実装する

worker

Herokuでは無料ライセンスでもwebアプリとは別に、worker用のdynoが1つ使えます。

ユーザーがアップロードした画像のサイズを縮小するだとか、夜間とか特定の時間にまとめて何らかのデータ集計をやっておくとかの目的で、キューをもとに実行されるもの、設定されたスケジュールをもとに実行されるもの、といったように何かしら時間のかかる処理やバッチを動かしたい時はworkerを使うと便利です。

この投稿ではどうやってworker用のDynoでNode.jsでバッチ処理を動かすか、を説明します。

Procfile

Procfileには以下のように、記述します。

worker: node worker.js

もし、webと同じアプリ上で動かしたければ、追記でOKです。

web: npm start
worker: node worker.js

Herokuのアプリを確認すると、Dynoは以下のようになります。
スクリーンショット 2016-03-24 9.11.03

node-cronモジュール

スケジュールを組んでバッチを実行したい場合、タイマーを実装して時間をチェックして、時間がきたらバッチを実行、としても良いかもしれませんが、node-cronモジュールを使うと、unixのcronと同じ要領でバッチのタスクを実行することができます。

var CronJob = require('cron').CronJob;

var workerJob = new CronJob({
  cronTime: '*/10 * * * * *', //毎10秒実行
  onTick: function() {
    //ここに実行したい処理を書く
    console.log('Hoge !');
  },
  start: true, //newした後即時実行するかどうか
  timeZone: 'Asia/Tokyo'
});
workerJob.start();

child_processモジュール

複数のバッチを実行する場合は起動したjsからさらに別のjsを実行することになります。
また、例えば使いたい外部サービスがNode.jsに対応していなかったとします。
外部サービスを利用するバッチはjavaで書くことになったので、jsじゃなくてjavaのMainクラスを実行したいということもあると思います。

そんな時はchild_processモジュールを使って、js上からコマンドを実行できるようにします。実際にはchild_processモジュールのexec、spawnのどちらかを使います。
簡単に書くと、以下な感じ。

var exec = require('child_process').exec;

exec('java -cp java/target/classes Main' //実行したいコマンド
    , function (error, stdout, stderr) {
          console.log('stdout: ' + stdout); //ログ
          console.log('stderr: ' + stderr); //エラーログ
      });