systemdのAfter・Wants・Requiresの違い|起動順序と依存関係
systemdでは「起動順序」と「依存関係」は別物です。After=だけでは相手を起動せず、Requires=だけでは希望する順序にならないことがあります。
このページで分かること
- After・Beforeが決めること
- Wants・Requiresが決めること
- AfterとWantsを両方書く理由
- RequiresとAfterの違い
- 実務での組み合わせと確認方法
先に結論
「相手を起動対象に加えるか」はWants=・Requires=、「どちらを先に起動するか」はAfter=・Before=で指定します。必要なら両方を併用します。
依存関係を適用前にレビュー
Unitを貼り付けて、After・Wants・Requiresの不足や不自然な組み合わせを確認できます。
最初に押さえる違い
| 設定 | 種類 | 相手を起動対象へ加える | 主な役割 |
|---|---|---|---|
After= | 順序 | いいえ | 両方が起動対象なら、自Unitを相手より後へ並べる |
Before= | 順序 | いいえ | 両方が起動対象なら、自Unitを相手より前へ並べる |
Wants= | 弱い依存 | はい | 相手も起動対象に加えるが、相手の失敗を強く連鎖させない |
Requires= | 強い依存 | はい | 相手を必須寄りの依存として起動対象に加える |
After=とWants=/Requires=は役割が違います。「相手も起動したい」と「相手の後に起動したい」の両方が要件なら、両方を書くのが基本です。AfterとBeforeは起動順序
After=database.serviceは、このUnitをdatabase.serviceより後へ並べる順序関係です。database.service自体を起動対象へ追加する設定ではありません。
After=を書いただけでは「database.serviceを先に起動してくれる」とは限りません。両方のUnitが同じ起動トランザクションに含まれたときに順序関係が効きます。停止処理では起動時の順序が逆向きに適用されます。たとえば自UnitがAfter=database.serviceなら、両者の停止が同じトランザクションに入った場合、自Unit側の停止がdatabase.serviceより先になります。
WantsとRequiresは依存関係
Wants=とRequires=は、指定したUnitを一緒に起動対象へ加える依存関係です。Wants=は弱く、依存先の起動失敗があっても自Unitの起動を必ず止める関係ではありません。
Requires=はより強い依存です。依存先が明示的にstop/restartされた場合は、自Unitにも停止・再起動が伝播します。ただし、依存先プロセスの異常終了などで依存先が予期せずinactiveになった場合まで、常に自Unitが追従して停止するわけではありません。そこまで連動させたい場合はBindsTo=とAfter=などの順序関係も含めて設計します。依存先の起動失敗時に自Unitを開始させたくない場合も、After=などの順序関係を合わせて確認することが重要です。
Wants=、依存先なしではサービスとして成立しないならRequires=を検討します。強くしすぎると障害時の停止範囲も広がるため、連鎖停止が本当に必要か確認してください。AfterとWants/Requiresは両方必要?
「相手を起動対象に加え、かつ相手より後に自Unitを起動したい」なら両方が必要です。 Search Consoleで出ている「systemd after wants」「systemd requires after」のような疑問は、ここを分けると判断しやすくなります。
| 要件 | 設定例 | 意味 |
|---|---|---|
| 相手が起動済みなら、その後に自Unitを開始したい | After=database.service | 順序だけを指定 |
| 相手も一緒に起動したいが、失敗しても自Unitは動ける | Wants=database.service | 弱い依存だけを指定 |
| 相手も起動し、その後に自Unitを開始したい | Wants=database.serviceAfter=database.service | 依存+順序 |
| 相手が必須で、その起動後に自Unitを開始したい | Requires=database.serviceAfter=database.service | 強い依存+順序 |
Requires=は「依存先を必要とする関係」、After=は「どちらを先に処理するか」です。Requires=を書けば自動的に希望する起動順序まで決まる、と考えないのがポイントです。よく使う組み合わせ
たとえばアプリケーションがdatabase.serviceなしでは成立せず、database.serviceの起動処理後に開始したい場合は次のように分けて指定します。
一方、監視エージェントのように「できれば一緒に起動したいが、失敗しても本体を止めたくない」ものなら、要件に応じてWants=を選べます。
ネットワーク依存の注意点
この組み合わせはnetwork-online.targetを起動対象に加え、自Unitをその後へ並べます。ただしnetwork-online.targetの意味は「常に外部通信できることを保証する」ではありません。実際にオンライン状態を待たせる仕組みは、NetworkManagerやsystemd-networkdなど利用中のネットワーク管理方式とwait-onlineサービスの構成に依存します。
さらに、起動後の回線断やDNS障害は別問題です。アプリ側のタイムアウト、再接続、リトライも含めて設計します。
daemon-reload を分けて実施します。手順は daemon-reloadはいつ必要? で確認できます。確認コマンド
Unitファイルを書いただけで判断せず、構文・実際に読み込まれた依存関係・逆依存を確認します。
Unitを変更した後は、必要に応じて設定を再読込してから確認します。