systemd/Timers (日本語) - ArchWiki

# systemd/Timers (日本語)

関連記事

- systemd
- systemd/ユーザー
- systemd/サービス
- systemd FAQ
- cron

タイマーは名前が `.timer` で終わる systemd のユニットファイルで、`.service` ファイルやイベントを制御します。cron の代わりとしてタイマーを使うことができます (#cron を置き換える を読んで下さい)。タイマーにはカレンダー時刻のイベントとモノトニック時刻のイベントのサポートが入っており、さらに非同期に実行することも可能です。

## タイマーユニット

タイマーは拡張子が `.timer` の systemd のユニットファイルです。他のユニット設定ファイルと似ていますが特別に `[Timer]` セクションが存在します。`[Timer]` セクションにはタイマーが作動する時間と処理を定義します。タイマーには2つのタイプがあり、どちらか一つを使って定義されます:

- モノトニックタイマーは刻々と変わる開始点と相応したタイムスパンの後に作動します。様々なモノトニックタイマーが存在しますがどれも次のような形式です: `OnTypeSec=`。`OnBootSec` と `OnActiveSec` は全てのモノトニックタイマーで共通です。モノトニックタイマーの詳細は `systemd.timer(5)` の man ページで説明されています。
- リアルタイムタイマー (別名ウォールクロックタイマー) は (cron のジョブと同じように) カレンダーイベントにあわせて作動します。`OnCalender=` オプションを使って定義を行います。カレンダーイベントやタイムスパンの引数構文については `systemd.time(7)` の man ページで説明されています。

## サービスユニット

それぞれの `.timer` ファイルには、対応する `.service` ファイルが存在します (例: `foo.timer` と `foo.service`)。`.timer` ファイルは `.service` ファイルを作動・制御します。`.service` に `[Install]` セクションは必要ありません。有効にするのは timer ユニットだからです。必要ならば、タイマーの `[Timer]` セクションで `Unit=` オプションを使うことで別の名前のユニットを制御することもできます。

## 管理

timer ユニットを使用するには、他のユニットと同じように有効化・起動します。起動しているタイマーを全て表示するには、次を実行:

    $ systemctl list-timers

    NEXT                          LEFT        LAST                          PASSED     UNIT                         ACTIVATES
    Thu 2014-07-10 19:37:03 CEST  11h left    Wed 2014-07-09 19:37:03 CEST  12h ago    systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
    Fri 2014-07-11 00:00:00 CEST  15h left    Thu 2014-07-10 00:00:13 CEST  8h ago     logrotate.timer              logrotate.service

Note: タイマーによって実行するサービスの状態は、今現在作動しているのでない限り、inactive になります。そして `/var/lib/systemd/timers` ディレクトリの `stamp-*` ファイルを使って systemd は `LAST` フィールドの情報を管理します。長さゼロのファイルで時刻フィールドを使用します。タイマーがズレる場合は、この stamp ファイルを削除することでタイマーの次の作動時に systemd が再構成を行います。

## サンプル

以下はサンプルのタイマー、service ユニットです。バックアップスクリプトのサービスです:

    /etc/systemd/system/mybackup.service

    [Unit]
    Description=Full system backup

    [Service]
    Nice=19
    IOSchedulingClass=2
    IOSchedulingPriority=7
    ExecStart=/path/to/mybackup/script

### リアルタイムタイマー

カレンダーイベントにあわせてバックアップを実行したい場合は、`OnCalendar` オプションを使います:

    /etc/systemd/system/mybackup.timer

    [Unit]
    Description=weekly full backup

    [Timer]
    OnCalendar=weekly
    Persistent=true

    [Install]
    WantedBy=timers.target

Tip: Shortcuts like `daily` and `weekly` refer to specific start times and thus any timers sharing such calendar events will start simultaneously. This can cause poor performance if the timers' services compete for system resources. Consider using more specific calendar events, which can be manually staggered (e.g. `OnCalendar=Wed, 23:15`).

### モノトニックタイマー

また、システムが起動する時に、一週間ごとに再起動でバックアップを実行したい場合、`OnBootSec` を `OnUnitActiveSec` と組み合わせます:

    /etc/systemd/system/mybackup.timer

    [Unit]
    Description=Weekly and post-boot backup

    [Timer]
    OnBootSec=15min
    OnUnitActiveSec=1w

    [Install]
    WantedBy=timers.target

Tip: リソースを消費するサービスでは、起動してすぐにタイマーを設定しないでください。ログインや X セッションに遅延が発生する可能性があります。

## cron を置き換える

おそらく cron が一番有名なジョブスケジューラですが、systemd のタイマーはその代替手段になりえます。

### メリット

タイマーを使う主要なメリットは、それぞれのジョブが固有の systemd サービスを使うというところに根ざします。そのメリットには以下のようなものがあります:

- タイマーとは別個にジョブを実行することが簡単にできます。これによってデバッグが楽になります。
- 特定の環境で動作するようにジョブを設定することができます (`systemd.exec(5)` man ページを参照)。
- ジョブを cgroups の支配下に置けます。
- 他の systemd ユニットに依存するようにジョブを設定できます。
- systemd の journal でジョブが記録されるのでデバッグが簡単です。

### 注意事項

- 冗長性: systemd を使って定期的なジョブを設定するには2つのファイルを作成して2回 `systemctl` コマンドを実行します。それに対して crontab には一行を追加するだけです。crontab を使って定期的なサービスを管理するツールとして systemd-crontab-generator と systemd-cron があります。もし、スケジュールされたジョブをまとめて見れるから crontab が好きだという場合は、`systemctl` でそれと同じことが可能です。#管理 を見て下さい。
- メール: ジョブが失敗した時にメールを送信する cron の `MAILTO` と同等なものは存在しません。各サービスに `OnFailure=` オプションを使うことで同じような機能を設定することはできます。
- ランダム遅延: インターバルを指定してタイマーの実行をランダムに分散する cron の `RANDOM_DELAY` と同じ機能はありません (バグレポートを参照)。同時に実行して欲しくないサービスには、手動でオーバーラップを少なくするようにタイマーを設定する必要があります。

タイマーを自動的にずらすには `AccuracySec` オプションが役に立つかもしれません。ただし"全てのローカルなタイマーユニット間で同期が行われる"ので注意してください (`systemd.timer(5)`)。言い換えれば、`AccuracySec` は全てのタイマーの作動時間を同じ分だけずらします。例えば、`AccuracySec=15m` を使っている `OnCalendar=daily` のタイマーユニットは全て、00:00 から 00:15 の間の同一時刻に関連するサービスを起動します。

## 参照

- systemd.timer man page on freedesktop.org
- Fedora Project wiki の systemd カレンダータイマーのページ
- Gentoo wiki の systemd タイマーサービスのセクション
- systemd-crontab-generator — crontab と anacrontab ファイルからタイマーとサービスを生成するツール

  https://github.com/kstep/systemd-crontab-generator || systemd-crontab-generator

- systemd-cron — cron スクリプトを実行する systemd ユニットが入っています。systemd-crontab-generator を使って crontab を変換。

  https://github.com/systemd-cron/systemd-cron || systemd-cron

Categories:

- Daemons and system services (日本語)
- Boot process (日本語)