Concrete CMS v9 よりバッチ処理をバックグラウンドで行うための新しい「タスク」機能
サーバーの設定を Cron じゃなくて、 Systemd timer を使って実装してみました。systemd timer を使う場合、root 権限があるサーバー (専用、VPS、クラウド) が必要な場合が多いです。
crond は日時でしか指定できないのですが、systemd は「前のプロセスが終わったら○秒後に実行」という設定も可能。つまりプロセスの二重起動の心配が無い!
またタイマーに依存関係も持たせることができてしまいます。
その分、設定も複雑になってしまいます。
今回はその手順を Concrete CMS に特化してお教えします。
Cron を使ってタスクを設定する場合はこちら
Concrete CMS タスク設定方法: Cron版 (V9 以降)
https://qiita.com/katzueno/items/ad7598565f4909c697ae
初期設定
1. Concrete CMS 管理画面での設定
- 管理画面 -> システムと設定 -> 自動化 -> 自動化設定 ページに訪問
- [Concrete URL]/index.php/dashboard/system/automation/settings
-
キューを確認する
を手動
に変更 - (オプション)
ログ
を保存したければ、ログ保存先をサーバー上に作成、そして「ログ」の設定を無効
からファイル
に変更し、Log Directory
に、サーバーパスを入力 (root権限のあるサーバー向け)- 例:
/var/log/ccm-task
で設定する場合sudo mkdir /var/log/ccm-task
sudo chown 【nginx:nginx, apache:apache, もしくはSSHユーザー】 /var/log/ccm-task
sudo chmod 755 /var/log/ccm-task
- ログは肥大化するので、logrotate を有効にしよう (STEP 7 参照 )
- 例:
-
スケジューラー
を有効
に変更 - 保存
2. タスクスケジューラーを設定
ccm-task-scheduler
というサービスを登録
sudo vi /etc/systemd/system/ccm-task-scheduler.service
内容はこちら。
-
User
,Group
には、現在の Concrete CMS 自信が利用しているユーザー・グループを入れてください。サンプルは nginx:nginx で Concrete CMS を動かしている際のサンプルです。 -
ExecStart
には、Concrete CMS の CLI を実行するためサーバーのフルパスをいれて入れてください
[Unit]
Description=ccm-task-scheduler
[Service]
User=nginx
Group=nginx
Type=oneshot
ExecStart=/var/www/vhosts/example.com/concrete/bin/concrete concrete:scheduler:run
次に ccm-task-scheduler
のタイマーを登録。
スケジューラーは
- サーバー起動時から1分待つ
- それからは1分ごとに起動
sudo vi /etc/systemd/system/ccm-task-scheduler.timer
内容はこちら。
[Unit]
Description=ccm-task-scheduler
[Timer]
OnBootSec=1min
OnUnitActiveSec=1min
Persistent=true
[Install]
WantedBy=timers.target
3. コンシューマーを設定
ccm-task-consumer
というサービスを登録
sudo vi /etc/systemd/system/ccm-task-consumer.service
-
User
,Group
には、現在の Concrete CMS 自信が利用しているユーザー・グループを入れてください。サンプルは nginx:nginx で Concrete CMS を動かしている際のサンプルです。 -
ExecStart
には、Concrete CMS の CLI を実行するためサーバーのフルパスをいれて入れてください - メモリリークやタイムアウトの心配もあるので、10分で一旦停止するようにします。もしもタスクの中に1実行時間が数分にもわたるようなタスクがあれば、実行時間を調整するべきかと思います。
[Unit]
Description=ccm-task-consumer
[Service]
User=nginx
Group=nginx
Type=simple
ExecStart=/var/www/vhosts/example.com/concrete/bin/concrete messenger:consume async --time-limit=600
次に ccm-consumer-scheduler
のタイマーを登録。
sudo vi /etc/systemd/system/ccm-task-consumer.timer
内容は以下の通り
- サーバー起動時から1分待つ
- コンシューマー自身が10分で停止するはず
- 停止したら1秒後に再起動
[Unit]
Description=ccm-task-consumer
[Timer]
OnBootSec=1min
OnUnitActiveSec=1s
Persistent=true
[Install]
WantedBy=timers.target
4. Config を反映させる
変更を加えたときは実施しましょう。
sudo systemctl daemon-reload
5. サービスをスタートアップ登録 & 有効化
サーバー再起動時にタイマーが起動するようにします。
sudo systemctl enable ccm-task-scheduler.service
sudo systemctl enable ccm-task-consumer.service
sudo systemctl enable ccm-task-scheduler.timer
sudo systemctl enable ccm-task-consumer.timer
タイマーのサーバー再起動時に起動するよう設定されているか確認
sudo systemctl is-enabled ccm-task-scheduler.timer
sudo systemctl is-enabled ccm-task-consumer.timer
6. サービスを起動
sudo systemctl start ccm-task-scheduler.service
sudo systemctl start ccm-task-consumer.service
sudo systemctl start ccm-task-scheduler.timer
sudo systemctl start ccm-task-consumer.timer
7. (オプション) logrotate を設定しよう
サーバー内にログファイルを保存するように設定したのなら、ログファイルが肥大化しないように、logrotate を設定しよう。
「1. Concrete CMS 管理画面での設定」のサンプルで /var/log/ccm-tasks/
ディレクトリ配下に保存するように設定したと仮定します。
sudo vi /etc/logrotate.d/ccm-task
週間で log rotate & 圧縮して、半年間保持する設定です。
/var/log/ccm-task/*log {
weekly
rotate 26
missingok
notifempty
compress
sharedscripts
}
8 systemd timer 動作確認・設定
動作確認方法
8-1. 各サービス・タイマーのステータス
sudo systemctl status ccm-task-scheduler.service
sudo systemctl status ccm-task-consumer.service
sudo systemctl status ccm-task-scheduler.timer
sudo systemctl status ccm-task-consumer.timer
8-2. タイマー実行確認
タイマーの前回実行時間、次回実行時間、経過時間などを確認できます。
sudo systemctl list-timers
8-3. ログ確認
sudo journalctl -e
8-4. 停止方法
sudo systemctl stop ccm-task-scheduler.timer
sudo systemctl stop ccm-task-consumer.timer
sudo systemctl disable ccm-task-scheduler.timer
sudo systemctl disable ccm-task-consumer.timer
9 Concrete CMS 側タスクの設定方法
実際にタスクをスケジュール設定し、タスクが正常に動くか確認しましょう。
9-1 タスクをスケジュールしてみる
sitemap.xml や索引インデックスのタスクを管理画面から設定します。
- 管理画面 -> システムと設定 -> 自動化 -> タスク に訪問
コンクリのトップ/index.php/dashboard/system/automation/tasks
- スケジュール設定したいタスクを選ぶ
- スクロールダウンし
タスク実行
メニューが表示されます -
すぐに
か定期的なタスクをスケジュール
の選択項目の後者を選択します。 -
Cron expression
という Cron 形式で実行時間を指定します。
9-2 Cron expression とは
曜日・月・日・時間・分を指定するための式みたいなものです。
アスタリスクをいれると、毎分・毎時間・毎日などと複数回設定できる様になります。
分・時・日・月・曜日
9-2-1 例: 毎朝8時に実行
0 8 * * * *
9-2-2 例: 1/1 0:00 に実行
0 0 1 1 * *
9-2-3 例: 毎週月曜日 0:00 に実行
0 0 * * * 1
これで、タスクによる Cron 設定を行うことができます。
10. Enviroment を使って Concrete CMS の config 環境を変える方法
Concrete CMS には、変数を設定することで、同じコードベースでも、本番・検証・開発の設定(Config)ファイルを用意し、変数に応じて読み込む config を変えることができる機能がついています。
参考: Concrete CMS で環境ごとに別の設定ファイルを読み込む方法
10-1 タスクスケジューラーの設定例
ENV名 production
で Concrete CMS のタスクを起動する例。Environment="CONCRETE5_ENV=production"
を適宜、変数を変えてください。
[Unit]
Description=ccm-task-scheduler
[Service]
User=nginx
Group=nginx
Type=oneshot
Environment="CONCRETE5_ENV=production"
ExecStart=/var/www/vhosts/example.com/concrete/bin/concrete concrete:scheduler:run
10-2 コンシューマーを設定
ENV名 production
で Concrete CMS のタスクを起動する例。Environment="CONCRETE5_ENV=production"
を適宜、変数を変えてください。
[Unit]
Description=ccm-task-consumer
[Service]
User=nginx
Group=nginx
Type=simple
Environment="CONCRETE5_ENV=production"
ExecStart=/var/www/vhosts/example.com/concrete/bin/concrete messenger:consume async --time-limit=600
参考
https://man.archlinux.org/man/systemd.timer.5
https://gamingpc.one/dev/systemd-timer-cheat/
https://wiki.archlinux.jp/index.php/Systemd/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC
https://forums.concretecms.org/t/how-we-can-set-env-for-task-in-v9-like-we-used-to-do-in-v8/4888