AL2023でsystemdのtimerを設定してシェルの定期実行をしてみた。

AL2023(Amazon Linux 2023)でシェルの定期実行をやろうとしてcronを見ていたのだけど、AL2023ではcronieはデフォルトでは含まれていませんでした。どうやらsystemdのタイマーに移行することを勧めているようです。AWSのユーザーガイドでは「Amazon Linux の将来のバージョン、場合によっては次のメジャーバージョンにはクラシックcronジョブのサポートが含まれなくなり、systemdタイマーへの移行が完了する可能性があります」とのことなので、systemdのタイマーを使うことにしました。

定期実行するシェルですが、curlコマンドを呼ぶだけのものです。ファイル名は curl.sh としました。ファイルの実行権限は 775 としています。


#!/bin/sh

curl http://localhost:8080/test/sample/fwmemoup > /dev/null 2>&1

if [ $? -eq 0 ]
then
	echo "curl success."
else
	echo "curl failed."
fi

このシェルを実行するServiceのユニット定義ファイルです。ファイル名は curlcmd.service です。


[Unit]
Description=Curl cmd service

[Service]
Type=oneshot
ExecStart=/home/user/tomcat/webapps/test/sample/curl.sh

Typeはoneshotにします。oneshotはプロセスが起動してすぐに処理が終わる場合(バッチ処理など)のときに使用するものです。ExecStartには curl.sh の配置場所を記載します。curlcmd.service は呼び出されたときにだけ実行する想定ですので、Installセクションの記載はありません(自動起動をさせることはないということ)。

curlcmd.service の配置場所ですが /etc/systemd/system の下に配置します。root権限が必要です。ファイル権限は 644 です。

Timerのユニット定義ファイルです。ファイル名は curl.timer です。


[Unit]
Description=Curl cmd timer

[Timer]
OnCalendar=*-*-* *:*:00
Unit=curlcmd.service

[Install]
WantedBy=multi-user.target

Unitの指定で curlcmd.service を呼び出します。定期実行するためにOnCalendarを使います。OnCalendarの書式です。

*は左から年、月、日、時、分を表しています。秒は00に設定されていて毎分0秒にタイマーが起動されるようです。

1分毎にタイマーを起動させる例です。

OnCalendar=*-*-* *:*:00

毎日、朝の4時にタイマーを起動させる例です。

OnCalendar=*-*-* 4:00:00

curl.timer では1分毎に curlcmd.service を呼ぶようにしています。Installセクションを記載してタイマーの自動起動はできるようにしました。タイマーの自動起動が失敗しても影響が出ないようにWantedByにします。通常起動でよいのでターゲットはmulti-user.targetです。

curl.timer 配置場所ですが curlcmd.service と同じく /etc/systemd/system の下に配置します。ファイル権限は 644 です。

これで必要なファイルはそろいました。systemdにユニット定義ファイを読み込ませます。

# systemctl daemon-reload

curl.timer と curlcmd.service の状態を確認します。


# systemctl status curl.timer
○ curl.timer - Curl cmd timer
     Loaded: loaded (/etc/systemd/system/curl.timer; disabled; preset: disabled)
     Active: inactive (dead)
    Trigger: n/a
   Triggers: ● curlcmd.service

# systemctl status curlcmd
× curlcmd.service - Curl cmd service
     Loaded: loaded (/etc/systemd/system/curlcmd.service; static)
     Active: failed (Result: exit-code) since Sun 2024-10-06 17:25:37 JST; 8min ago
   Main PID: 1244299 (code=exited, status=203/EXEC)
        CPU: 919us

ここで問題が。。

curl.timer のほうは問題なさそうですが、curlcmd.service のほうが failed となっています。curlcmd.service のユニット定義ファイルを見直してみると curl.sh のスペルを間違えていました。ですので間違いを修正して再度 systemctl daemon-reload をしたのですが、現象変わらずでした。

どうもsystemdの再読込とサービスのリスタートが必要なようです。

# systemctl daemon-reload
# systemctl restart <サービス名>

とはいえ、curlcmd.service は常駐プロセスではなくすでに処理終了しているためどうすればよいのかよくわからず、OSの再起動をしました。あとから思ったのですが、メインプロセスのPIDを指定してkillをすれば良かったのかもと思いましたが、すでにOS再起動のあとだったので確認はできずです。

再起動後の curlcmd.service 状態です。


# systemctl status curlcmd
○ curlcmd.service - Curl cmd service
     Loaded: loaded (/etc/systemd/system/curlcmd.service; static)
     Active: inactive (dead)

うまくいったようです。タイマー起動ではなく手動実行で curlcmd.service を実行してみます。

# systemctl start curlcmd


# systemctl start curlcmd
# systemctl status curlcmd
○ curlcmd.service - Curl cmd service
     Loaded: loaded (/etc/systemd/system/curlcmd.service; static)
     Active: inactive (dead)

10月 06 18:03:45 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: Starting curlcmd.service - Curl cmd service...
10月 06 18:03:46 ip-172-26-3-121.ap-northeast-1.compute.internal curl.sh[2382]: curl success.
10月 06 18:03:46 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: curlcmd.service: Deactivated successfully.
10月 06 18:03:46 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: Finished curlcmd.service - Curl cmd service.

無事起動できているようなので、タイマーも起動させます。

# systemctl start curl.timer


# systemctl start curl.timer
# systemctl status curl.timer 
● curl.timer - Curl cmd timer
     Loaded: loaded (/etc/systemd/system/curl.timer; disabled; preset: disabled)
     Active: active (waiting) since Sun 2024-10-06 18:08:29 JST; 17s ago
    Trigger: Sun 2024-10-06 18:09:00 JST; 13s left
   Triggers: ● curlcmd.service

10月 06 18:08:29 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: Started curl.timer - Curl cmd timer.

curl.timer のほうはActiveで常駐しているようです。

curl.timer と curlcmd.service のジャーナルのログを確認してみます。

# journalctl -u curl.timer
# journalctl -u curlcmd


# journalctl -u curl.timer
10月 06 18:08:29 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: Started curl.timer - Curl cmd timer.

# journalctl -u curlcmd
 :
10月 06 18:09:43 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: Starting curlcmd.service - Curl cmd service...
10月 06 18:09:43 ip-172-26-3-121.ap-northeast-1.compute.internal curl.sh[2609]: curl success.
10月 06 18:09:43 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: curlcmd.service: Deactivated successfully.
10月 06 18:09:43 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: Finished curlcmd.service - Curl cmd service.
10月 06 18:10:43 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: Starting curlcmd.service - Curl cmd service...
10月 06 18:10:43 ip-172-26-3-121.ap-northeast-1.compute.internal curl.sh[2664]: curl success.
10月 06 18:10:43 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: curlcmd.service: Deactivated successfully.
10月 06 18:10:43 ip-172-26-3-121.ap-northeast-1.compute.internal systemd[1]: Finished curlcmd.service - Curl cmd service.
 :

ジャーナルログに1分間隔で curlcmd.service の出力を確認できました。

最後に curl.timer の自動起動を設定しておきました。

# systemctl enable curl.timer


# systemctl enable curl.timer
Created symlink /etc/systemd/system/multi-user.target.wants/curl.timer → /etc/systemd/system/curl.timer.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です