Node.jsコードの実行をスケジューリングする4つの方法

July 06, 2020
執筆者

4 ways to schedule Node.js code

この記事はTwilio Developer EvangelistのNathaniel Okenwaこちら(英語)で執筆した記事を日本語化したものです。

JavaScriptを使用して定期的なタスクを実行したことがあるでしょうか? 私は常に、反復タスクを自動化する方法を模索しています。多くの単調な作業をする心理的な負担を和らげるためにも、コードの力が大変役立ちます。多くのアプリケーションは、管理、システムメンテナンス、毎日のバックアップからメールを初めとするメッセージの送信など、重要なタスクを定期的に実行する必要もあります。そこでcronの出番です!

Cron式

Cronを使用してジョブの実行時間をスケジュールし、決めた日時に自動で実行できます。Cron式は、タスクの実行スケジュールを定義する文字列です。こちらのリンクを参考にしてCron式を作成できます。例えば、Node.jsスクリプトを毎朝9時に実行するとしましょう。そのcron式は次のようになります。

0 0 9 * * * [command]

それぞれのパートごとに見てみましょう。式の(最初を除く)の5つの部分は、分、時、日付、月、曜日に対応する文字列で構成されます。時間単位xで毎回コマンドを実行するには、その部分に*を記入します。上記のcron式では、0分、9時、毎日、毎月、全曜日にコマンドが実行されることになります。

間隔をおいてコマンドを実行するには、/を使用します。例えば、1日おきの正午にコマンドを実行するのであれば、次のような式になります。

0 0 12 1/2 * * [command]

Cron式を理解したところで、毎日のメッセージ送信に使用できる4つの方法を見てみましょう。

Crontabのローカル実行

UNIXシステム

crontabはUNIX(ファミリー)オペレーティングシステムに組み込まれたソフトウェアユーティリティです。一連のジョブリストがcrontabファイルに格納されます。UNIXベースのOS(Linux、MacOSなど)では、次のコマンドによりcrontabファイルを編集できます。

$ crontab -e

Crontabファイルの各エントリは、スペースで区切られた6つのフィールドで構成されます。最初の5つがcron式を構成し、6番目が実行するコマンドです。例えば、nodeを使用して「index.js」ファイルを実行するとします。通常、コマンドラインで次のコマンドを実行します。

$ node index.js

ただし、このcronエントリには、cron式、nodeへの絶対パス(通常は/usr/local/bin/node)、index.jsファイルへの絶対パスという3項目を含める必要があります。このcronエントリは次のようになります。

0 0 9 * * * [path/to/node] [path/to/index.js]

自分のJavaScriptコードをcrontabファイルにエントリとして追加してみてください。現在スケジュールされているジョブを確認するには、次のコマンドを随時実行します。

$ crontab -l

こうして簡単にnode.jsコードをスケジュールし、すべてのローカルリソースに引き続きアクセスできますが、いくつかの制約が存在します。まず、スケジュールしたコードを実行するには、コンピューターが常にオンラインでなければなりません。マシンを常時稼働しておかなくてもいいように、インターネット上でコードを実行する方法を考えてみます。

Windows

Windows環境では2つの方法があります。まず、Linux用Windowsサブシステムをインストールしてコマンドを実行する方法です。

$bash

Linux環境を実行し、上記のようにcrontabスケジューラを利用できます。もう1つが、powershellやcmdからスケジュールされたWindowsのタスクを使用する方法です。スケジュールされたタスクを使用するには、nodeを起動するバッチファイル(.bat)を作成する必要があります。とてもシンプルなファイルは次のようになります。

node index batch file

WindowsスケジューラはCron式を使用しませんが、所定の間隔で実行されるようジョブをスケジュール設定できます。スケジュールされたタスクを作成し、Node.jsコードを起動するバッチファイルを実行するには、次のコマンドを実行します。

schtasks /create /tn myTask /tr [path/to/.bat/file] /sc DAILY /st 09:00

それぞれパートごとに見てみましょう。次のコマンドにより新しいタスクを作成します。

  • /tn - タスク名。タスク名myTask(注: 一意のタスク名を使用)
  • /tr - タスク実行。スクリプトファイルの絶対パス
  • /sc - スケジュールタイプ。分、時間、週ごと、その他の設定が可能
  • /st - 開始時間。最初のタスクを開始する時間。続くタスクは所定の間隔で実行される

その他にもオプションが多数あり、さらに複雑なスケジュールを設定できます。Microsoftドキュメントの総合ガイドschtasksの使用法が記載されています。

クラウドサーバー

コードをインターネットで実行するには、何らかのインフラストラクチャサービスが必要になります。AWS EC2、Google Compute Engine、DigitalOcean Droplets、Azure Virtual Machinesなど、多くの一般的サービスが利用できます。サービスの違いについて詳しくは述べませんが、サービスごとに初期セットアップを完了すれば、ローカルで実行したのと同じようにcrontabツールを使用できるようになります。

クラウドサーバーは24時間365日オンラインで使用できる便利な環境であり、インターネットがすぐに崩壊することもないでしょう。しかし、サーバーのセットアップと維持は時間のかかる作業です。また、「常時稼働」のサーバーであるため技術的には料金を支払い続けていますが、多くのプロバイダーが提供している無償サービスの範囲は超えないはずです。

クラウド関数

サーバーの維持は大きな負担がかかり、思う以上に多くの作業を要します。利用期間中に実行するジョブがなくても、年間のサーバー料金が発生する問題もあります。クラウドサービスには、設定したスケジュールで実行できるクラウド関数を提供するものもあります。

こちらに例を挙げます。

このリストの中にお使いのクラウドホストがなくても、Cronスケジュールジョブを設定できないわけではありません。詳細については、各クラウドホストのドキュメントを確認してください。クラウドサーバーと同じく、Cron関数は常時利用可能で改善がなされ、使用した分だけの料金で済みます。

クラウドトリガー

この方法は上記のクラウド関数と似ており、JavaScriptコードをクラウド関数内でホストする形をとります。下で紹介するような一部のサービスでは、任意のURLに定期的にHTTPリクエストを送ることができ、特定のベンダーに縛られずにすむため便利です。クラウド関数サービスにはCron機能が搭載されていないことが多いため、このオプションは私のお気に入りです。好きなクラウド関数サービスを使い、コードをホストするだけで済みます。私の個人的なお気に入りのクラウド関数はTwilio Functionsです。この関数の起動をスケジュールし、Node.jsコードを実行できます。

クラウドトリガーのいくつかお気に入りをあげておきます。

クラウドトリガーを使用する場合、HTTPリクエストによりコードを起動できるのであれば、コードの場所は問題になりません。このため、特にベンダーにより関数が異なる場合に便利な方法です。しかし、スケジュール設定されたジョブを管理する場所が増えることを意味し、管理対象も増えます。

まとめ

Node.jsのコードが定期的に実行されるようスケジュールを設定するには、さまざまな方法があります。Cronジョブの設定方法には、それぞれ長短があり、開発者のニーズに応じて好みも異なります。個人的には、Twilio FunctionsとGoogle Cloud Schedulerの組み合わせがお気に入りです。サーバーレス環境では、サーバーを稼働する必要なくコードをスケジュール設定できます。すばらしいですね!

皆さんによるJavaScriptコードのスケジュール設定例を楽しみにしています。皆さんの取り組みをこちらまでお知らせください。