Cron
Moodleの「cron」プロセスは、バックグラウンドで定期的に実行する必要があるPHPスクリプト(Moodleの標準インストールに含まれています)です。Moodleのcronスクリプトは、さまざまなタスクをそれぞれ異なるスケジュール間隔で実行します。
重要:サーバ上でMoodleのcronプロセスの設定を省略しないでください。cronがなければ、サイトは正しく動作しません。
ごみ箱を使用している場合の活動の非同期削除に必要なため、cronを毎分実行することをお勧めします。
cronプログラム(Moodleスクリプトを実行するもの)は、Unixベースのシステム(LinuxおよびOSXを含む)の中核をなす部分で、時間に依存するあらゆる種類のサービスの実行に使用されています。Windowsでは、Windowsのタスクスケジューラでタスクを作成し、一定の間隔で実行するように設定するのが最も簡単な方法です。共有ホスティングでは、cronの設定方法についてのドキュメントを探す(またはサポートに問い合わせる)必要があります。ほとんどの共有ホスティングシステムはサイトの管理にCPanelを使用しており、通常はパネルにCronジョブのセクションがあります。
基本的に、この作業はシステムのcronジョブの一覧に1つのコマンドを追加することです。Unixベースのシステムでは、この一覧は「crontab」というファイルで、すべてのユーザが持っています。
一般的な説明
お使いのサーバの種類については後のセクションを参照してください。このセクションには一般的な背景情報が含まれています。
cronの実装には、基本的に2つのステップがあります。
- 実行する正しいコマンドを特定する
- システム上でそのコマンドを置く正しい場所を見つける
Moodleのcronコマンドを決める
Moodleには、cronを実行するための2つの異なる方法があり、それぞれMoodleインストール内の異なるスクリプトを使用します。次のとおりです...
- CLI(コマンドラインインタプリタ)スクリプト。これは次のパスにあります。
/path/to/moodle/admin/cli/cron.php
迷った場合は、このスクリプトを使用するのが正解です。これはコンピュータ上の「PHP CLI」プログラムで実行する必要があります。そのため、最終的なコマンドは次のようになります。/usr/bin/php /path/to/moodle/admin/cli/cron.php
コマンドラインでこれを試して、動作するかどうかを確認できます(確認すべきです)。警告:コマンドラインのPHPのバージョンが、選択したMoodleのバージョンと互換性があることを確認してください。コマンドラインのPHPプログラムはウェブサイトを実行しているものとは別で、常に同じバージョンとは限りません。 - 何らかの理由でCLIスクリプトを実行できない場合は、ウェブベースのスクリプトがあります。ただし、これは現在非推奨となっており、将来のバージョンで削除される可能性があります。これはウェブブラウザから実行する必要があり、http://your.moodle.site/admin/cron.phpのようなウェブURLでアクセスします。コマンドラインベースのウェブブラウザ(例:wget)を使用できるので、最終的なコマンドは次のようになります。
/usr/bin/wget http://your.moodle.site/admin/cron.php
この方法には、*どこからでも*実行できるという利点があります。お使いのマシンでcronを動作させられない場合は、別の場所から実行できます。
ウェブベースのMoodle cronコマンド
- 選択できる場合は、ウェブベースのcronを使用しないでください。将来のMoodleバージョンで削除される可能性があります。
- Moodle 2.9以降、デフォルトではcronジョブをウェブから実行できなくなりました。次のエラーメッセージが表示されます。
!!! 申し訳ございません、このページへのインターネットアクセスは管理者より無効にされています。 !!!
- これはダッシュボード ► サイト管理 ► セキュリティ ► サイトポリシーで「コマンドラインでのみcronを実行する」の選択を解除することで変更できます。
- 「ウェブ経由でcronを実行することにより、匿名ユーザに機密情報を晒してしまいます。そのため、コマンドラインによるcronの実行またはリモートアクセスに対してcronにパスワードを設定することをお勧めします。」という警告が表示されます。
- その後、「リモートアクセスのcronパスワード」を入力できます。このフィールドを空のままにした場合、パスワードは不要です。
- つまり、次の形式のURLでパスワードを指定しない限り、cron.phpスクリプトをウェブブラウザから実行できなくなります。
http://site.example.com/admin/cron.php?password=opensesame
コマンドを置く正しい場所を見つける
これは使用しているシステムによって大きく異なるため、お使いのプラットフォームまたはホスティングのドキュメントを探して読む必要があります。ほとんどの場合、Moodleのcronを実行するには、正しいコマンド(上記)を決め、そのコマンドとそれを実行する時刻を何らかのファイルに追加します。これは専用のユーザインタフェースを使用する場合もあれば、ファイルを直接編集する場合もあります。
CLIバージョンを使用する場合は、cronプロセスが正しいユーザとして実行されるようにする必要もあります。ウェブバージョンではこれは問題になりません。
例:Ubuntu/Debian Linuxにcronをインストールする場合。rootとしてログインしていることを前提とします。
crontabコマンドを使用して、www-dataユーザのcrontabエディタウィンドウを開きます。これは、DebianベースのシステムでApache(ウェブサーバ)を実行するユーザです
$ crontab -u www-data -e
エディタウィンドウが開きます。CLIのcronスクリプトを1分ごとに実行するには、次の行を追加します。
* * * * * /usr/bin/php /path/to/moodle/admin/cli/cron.php >/dev/null
注:最後の>/dev/nullはすべての出力を「ごみ箱」に送り、1分ごとにメールが届くのを防ぎます。
システムでのcronの設定
お使いのサーバの種類に応じた情報を選択してください。
- UnixまたはLinuxでのcron- さまざまなUNIXおよびLinux系オペレーティングシステムでのcronサービス
- Windows OSでのcron - Windowsでのcronサービス
- Apple OSX - 組み込みの「crontab」サービスを使用します。これはUnixまたはLinuxでのcronとまったく同じです。ただし、launchdを使用して「Appleのやり方」で行うこともできます。Mac OS Xでのcronを参照してください。
- ウェブホスティングサービスでのcron- さまざまなウェブホスティングの例におけるcronサービス
特定のホスト向けの手順もあります(最新の情報かどうか確認してください)。
サードパーティのcronサービスの使用
自分のサーバでホストするcronを使用する以外に、サードパーティのcronサービス(通常、webcronと呼ばれます)を使用することもできます。
- cron-job.orgは無料のサービスです(1分間隔のcronが可能です)。
- EasyCron - crontabやその他のタスクスケジューラでcronジョブを設定する必要をなくすwebcronサービスプロバイダです。
- WebCron - 無料で簡単なwebcronサービスプロバイダです。
Moodleのcron設定
管理者は、サイト管理の「サイトセキュリティ設定」で、コマンドラインのみによるcronの実行、またはリモートアクセスのcronパスワードを設定できます。
リモートcron
「ウェブベース」バージョンのcronを使用する場合、cronプロセスをMoodleサーバとは別のマシンに置いてもまったく問題ありません。たとえば、Unixサーバ上のcronサービスから、WindowsベースのMoodleサーバ上のcronウェブ「ページ」を呼び出すことができます。
タスクのスケジューリング
管理者は、管理 > サイト管理 > サーバ > スケジュールタスクでcronタスクのスケジュールを細かく設定できます。スケジュールタスクを参照してください。
複数のMoodleサーバでのcronの実行
- タスクは並列に実行でき、プロセスはロックを使用してタスクが同時に実行されるのを防ぎます。そのため、同じMoodleインスタンスを提供する複数のウェブサーバからcronを起動できます。
- 同じサーバで異なるMoodleインスタンスを実行している場合は、Moodleインスタンスごとにcronジョブが必要です。(1台のApacheウェブサーバでも、バーチャルホスト機能を使用して、異なるドメインで異なるMoodleインスタンスを実行できます https://httpd.apache.org/docs/2.2/vhosts/index.html。)
スケジュールタスクのデバッグ
特定のcronタスクが正しく動作しない場合があります。Moodle 2.7より前のバージョンでは、例外をスローするcronタスクがあると、cronの残りの部分が実行されなくなりました。cronが毎回完了しているかどうかを監視する唯一の方法は、cronの実行結果の出力を自動的にチェックする仕組みを追加することでした(例:「Cron completed at 」という文字列を検索する)。
Moodle 2.7以降では、1つのスケジュールタスクが失敗しても、残りのタスクの完了が妨げられることはありません。いずれかのスケジュールタスクが失敗すると、そのタスクは失敗としてマークされ、再試行がスケジュールされます。タスクが失敗し続けると、次回のスケジュール時刻は後ろに延ばされ、最終的には最大で24時間に1回試行されるようになります。ただし、スケジュールタスクの管理ページを確認すれば、現在失敗しているタスクがあるかどうかがわかります(そのタスクの失敗時の待機はゼロ以外になっています。これは、失敗したタスクを再試行するまで待機する秒数です)。失敗しているタスクをデバッグする簡単な方法は、CLIのスケジュールタスクランナーを使用してそのタスクをすぐに実行し、出力を監視することです。
ロギングと監視
理想的には、cronの出力もどこかにログとして記録し、問題がないか監視する必要があります。次のページにアクセスすると、cronの全体的なステータスを監視し、エラーがないことを確認できます。
サイト管理 / レポート / システムステータス(/report/status/index.php)
また、Check API(https://docs.moodle.org/dev/Check_API)のCLIコマンドを使用するか、https://github.com/catalyst/moodle-tool_heartbeat のようなプラグインを利用して、このステータスレポートをIcinga / Nagiosなどのツールと連携させることもできます。
/admin/cli/checks.php
エラーがある場合は、スケジュールタスクページの「ログ」列から、最近実行されたタスクの詳細を確認できます。ただし、アドホックタスクの失敗はここには表示されません。
サイト管理 / サーバ / タスク / スケジュールタスク(/admin/tool/task/scheduledtasks.php)
アドホックタスクの失敗を確認するには、タスクを自分で手動で再実行してエラーを確認するか、あらかじめログを収集して確認できるようにしておく必要があります。1台のマシンで動作しているMoodleであれば単純なログファイルにログを記録できます。クラスタの場合はsyslogdなどを使用するとよいでしょう。例:
* * * * * /usr/bin/php /path/to/moodle/admin/cli/cron.php 2>&1 | /usr/bin/logger ...
低レイテンシのアドホックタスク
cronが実行されるたびに、スケジュールタスクの後にアドホックタスクも実行されます。スケジュールタスクは最大でも1分に1回しか実行できませんが、アドホックタスクはいつでもキューに追加される可能性があり、一般にできるだけ早く処理し、スケジュールタスクが先に実行されるのを待たずに済むようにしたいものです。通常のadmin/cli/cron.phpだけを実行している場合、まずすべてのスケジュールタスクの処理を待たなければならない可能性があるだけでなく、cronがすでに終了していれば、処理されるには次の分にcronが再び開始されるまで待つ必要があります。
代わりに、メインのcronプロセスと並列に実行される専用のアドホックタスクプロセッサを1つ以上実行できます。
* * * * * /usr/bin/php /path/to/moodle/admin/cli/adhoc_task.php --execute --keep-alive=59 * * * * * /usr/bin/php /path/to/moodle/admin/cli/adhoc_task.php --execute --keep-alive=59 ...
Moodle 3.9以降、—keep-aliveオプションはデーモンのように動作します。キューが空になっても終了せず、新しいタスクがキューに追加されるのを待つため、できるだけ早く処理を開始できます。
複数のプロセスによるcronのスケールアップ
サイトが成長するにつれて、多くのスケジュールタスクは完了までに時間がかかるようになり、処理が必要なアドホックタスクもより多くキューに追加されるようになります。cronシステムは並列に動作するように設計されていますが、個々のプロセスは一度に1つのタスクしか処理できないため、複数のcron CLIを実行する必要があります。一般に、複数のcronインスタンスを実行する必要が生じるまでに、専用のcronインスタンス上でかなり多くのcronプロセスを実行できます。複数のプロセスを実行するには、毎分複数のcronプロセスを起動するだけです。
* * * * * /usr/bin/php /path/to/moodle/admin/cli/cron.php * * * * * /usr/bin/php /path/to/moodle/admin/cli/cron.php * * * * * /usr/bin/php /path/to/moodle/admin/cli/cron.php ⋮ * * * * * /usr/bin/php /path/to/moodle/admin/cli/adhoc_task.php --execute --keep-alive=59 * * * * * /usr/bin/php /path/to/moodle/admin/cli/adhoc_task.php --execute --keep-alive=59 * * * * * /usr/bin/php /path/to/moodle/admin/cli/adhoc_task.php --execute --keep-alive=59 ⋮
特定のプラグインやシステムは非常に多数のアドホックタスクや、処理に長時間かかるタスクを生成することがあるため、adhoc_task.phpプロセスの数を増やすことは特に重要になる場合があります。特に、ドキュメント変換や自動バックアップなどのタスクは、デフォルト設定のままにしておくと、処理されるよりも速く溜まっていく可能性があります。
デフォルトでは、同時に実行できるのはスケジュールタスク3件およびアドホックタスク3件のみです。そのため、プロセスを追加する場合は、許可する同時実行数のレベルを上げる必要があります。
サイト管理 > サーバ > タスク > タスク処理
または、config.phpで次のように設定します。
$CFG->task_scheduled_concurrency_limit = 20; // Defaults to 3
$CFG->task_adhoc_concurrency_limit = 50; // Defaults to 3
これらをどのような値に設定する場合でも、それらをホストするサーバがこれだけの数のプロセスを無理なく処理できることを確認してください。多くの場合、ボトルネックになるのは共有サービス、通常はデータベースです。
非常に長時間実行される特定の種類のタスクが、利用可能なタスクプロセスをすべて使い果たし、他のタスクがまったく実行されなくなる場合があります。たとえば、CLIプロセスが5つあり、タスクキューに自動バックアップ用のアドホックタスクが20件あって、それぞれの完了に10分かかる場合、5つのプロセスはすぐにすべてバックアップに占有され、他のことは何もできなくなります。ドキュメント変換やフォーラムのメールなど、その他の小さくて非常に速く軽いタスクは、バックアップが完了してプロセスが空くまで送信されません。これに対処するには、特定の種類のアドホックタスクの同時実行数を制限できます。目安としては、「重い」タスクがすべてそれぞれの上限まで使い切った場合でも、キューに追加される可能性のあるその他のタスクのために、アイドル状態で待機しているプロセスがまだいくつか残っているようにします。
自動バックアップは最も問題を起こすことが知られているため、仮に50個のアドホックタスクプロセスを同時に実行している場合、妥当な制限としては、バックアップが消費するプロセスをその半分以下、つまり最大25個に抑えることが考えられます。
config.phpで次のように設定します。
$CFG->task_concurrency_limit = [
'core\task\course_backup_task' => 25,
'core_course\task\course_delete_modules' => 5,
];
関連項目
- スケジュールタスク
- 英国オープン大学のSam MarshallによるCronに関する役立つブログ記事
- cron機能に関するウィキペディアの記事
- MDL-50694 - Cron message "The operation timed out while waiting for a lock" isn't really an error
フォーラムディスカッション:
- How to log the output of a Scheduled Task on Windows - このディスカッションでは、Windowsのスケジュールされたタスクで問題が発生していて、スケジュールされたタスクの出力をログファイルに記録する必要がある場合に非常に役立つ便利な方法が説明されています。