私はsystemd .serviceファイルを作成しています。Requires=
とAfter=
の違いを理解するのに助けが必要です。 man page は、Requires=
が「他のユニットへの要件の依存関係を構成する」と述べています。およびAfter=
"ユニット間の順序依存関係を構成します。"違いは何ですか?
After=
はサービスの順序を設定し(XはYの後にのみ実行)、Requires=
は依存関係を示します。順序を指定しない場合、依存するサービスと同時に依存するサービスが開始されます。また、私がそれを理解する方法(私はそれをテストすることができず、参照を見つけることができません)、After=
は「疎結合」であり、そのようなステートメントを持つサービスは、 After=
行で指定された名前はまったく開始されませんが、Require=
は、要件が満たされていない場合は開始されません。
引用 https://www.freedesktop.org/software/systemd/man/systemd.unit.html :
必須=
他のユニットの要件依存関係を設定します。このユニットがアクティブになると、ここにリストされているユニットもアクティブになります。他のユニットの1つが非アクティブ化されるか、そのアクティブ化が失敗した場合、このユニットは非アクティブ化されます。このオプションは複数回指定することも、1つのオプションでスペースで区切られた複数のユニットを指定することもできます。その場合、リストされたすべての名前の要件依存関係が作成されます。要件の依存関係は、サービスが開始または停止される順序には影響しないことに注意してください。これは、After =またはBefore =オプションで個別に構成する必要があります。ユニットfoo.serviceが、Requires =で構成されたユニットbar.serviceを必要とし、After =またはBefore =で構成されていない場合、foo.serviceがアクティブ化されていれば、両方のユニットが同時に開始され、それらの間で遅延は発生しません。多くの場合、失敗したサービスを処理する際により堅牢なシステムを実現するために、Requires =の代わりにWants =を使用することをお勧めします。
そして
前=、後=
スペースで区切られたユニット名のリスト。ユニット間の順序依存関係を設定します。ユニットfoo.serviceに設定Before = bar.serviceが含まれ、両方のユニットが開始されている場合、foo.serviceが開始されるまでbar.serviceの開始は遅延されます。この設定は、Requires =で構成されている要件の依存関係から独立しており、直交していることに注意してください。 After =およびRequires =オプションの両方にユニット名を含めることは一般的なパターンです。この場合、リストされているユニットは、これらのオプションで構成されているユニットの前に起動されます。このオプションは複数回指定できます。その場合、リストされているすべての名前の順序依存関係が作成されます。 After =は、Before =の逆です。つまり、After =は、リストされたユニットの起動が完了した後に構成済みユニットが確実に起動するのに対し、Before =は、その逆、つまり、リストされたユニットが起動する前に構成済みユニットが完全に起動することを保証します。順序の依存関係がある2つのユニットがシャットダウンされると、起動順序の逆が適用されることに注意してください。つまり、ユニットが別のユニットでAfter =を使用して構成されている場合、両方がシャットダウンされると、前者は後者の前に停止されます。 2つのユニット間に順序付けの依存関係がある場合、一方のユニットがシャットダウンされ、もう一方が起動された場合、シャットダウンは起動前に行われます。順序の依存関係がAfter =またはBefore =であるかどうかは関係ありません。また、一方がシャットダウンされ、もう一方が起動されている限り、どちらがシャットダウンされても問題ありません。すべての場合において、シャットダウンは起動前に命令されます。 2つのユニット間に順序の依存関係がない場合、それらは同時にシャットダウンまたは起動され、順序付けは行われません。
主な違いの1つは、
After
は、ユニットが既にアクティブ化されているかどうかのみをチェックし、指定されたユニットを明示的にアクティブ化しません。Requires
にリストされているユニットは、ユニットとともにアクティブ化されます。必要なユニットのいずれかが起動に失敗した場合、ユニットはアクティブ化されません。ユニットファイルtest-app.service
があるとします。
[Unit]
Description=test app
After=network-online.target
このステートメントを実行すると、次のようになります。
After
はnetwork-online.target
かどうかをチェックします。network-online.target
が開始されていない場合は待機します。test-app
は、network-online.target
がアクティブになった後にのみ開始します代わりにRequires
があった場合、
[Unit]
Description=test app
Requires=network-online.target
このステートメントを実行すると、次のようになります。
network-online.target
とtest-app
は一緒にアクティブ化されますnetwork-online.target
が起動しない場合、test-app
はアクティブ化されません。systemdはジョブマネージャーです。 manページは、物事がどのように機能するかに関してはあまり正確ではありません。
起動すると、systemdはアンカージョブのジョブ(つまり、default.targetの開始ジョブ)で構成されるトランザクションを構築します。これらすべての依存関係と関係が行うことは、どのジョブがどのようにトリガーされるかを定義することです。順序付けは、他のすべてのジョブが待機するジョブを定義します。したがって、default.targetユニットはこのすべての中心にあります。そのため、ユニットを有効にすると、systemctl enableを介して、前方依存関係systemdが従うことができることを示すファイルシステムシンボリックリンクを作成する逆依存関係を使用します(また、最初の場所)。同様に、一部のユニットを手動で開始すると、そのユニットはアンカーになり、トランザクションはそれに対して計算されます。
あまり詳しくは説明しませんが、Requires =とAfter =の機能について説明します。
Requires =を指定すると、開始ジョブがトリガーされたときに(明示的に、または依存関係を通じて、内部的に区別がありません)、systemdが必要なユニットの開始ジョブをトリガーします。また、このユニットが停止したとき(注:停止し、それ自体では停止しない)または再起動したときに停止ジョブをトリガーするプロパティもあります。つまり、依存関係/ systemctlによって停止/再起動が発生した場合は、停止/再起動することになります。ただし、それ自体がダウンした場合、ジョブがなかったため停止せず、systemdの関与なしに状態変化が発生しました。ここでBindsTo =を使用します(明らかな理由により、systemdの関与なしに非アクティブにできるデバイスユニットと同様です)。
ここで、Requires =だけでそれが行うことはきちんとしているため、After =の使用をお勧めします。開始ジョブが失敗した場合はrequireeをキャンセルします。ただし、このキャンセルはwrtジョブでのみ機能します。つまり、他のユニットが順序を定義していない場合、systemdは両方を並行してトリガーします。開始ジョブが失敗する前にその開始ジョブが完了すると、キャンセルされません(実際にはキャンセルできません)。 。 After =の使用は、必要なユニットの開始ジョブが終了するまで他のジョブが待機し続けることを意味し、結果によっては、失敗した場合、ユニットの待機開始ジョブはJOB_DEPENDENCYジョブ結果でキャンセルされます(黄色の[DEPEND]を使用する理由)そのような場合の起動時)。したがって、この無効化の効果は、After =を使用しないと不確定です。
これが、他のユニットの起動を待たない場合は、After =なしでWants =を使用するのが適切な理由です。無効化がないため、競合は発生しません。その場合、それは単なる同期メカニズムにすぎません。
また、起動時に両方を有効にし、互いに必要とせず、順序付けのみを定義することもできます。その場合、両方が同じトランザクションの一部としてプルされると、順序付けされます(または、もう一方のジョブがトリガーされた場合)後に実行したいユニットのジョブが実行されている間、トランザクション全体で、それが完了するのを最初に待ちます)。
仕事がない場合、注文はそのユニットに影響を与えません。ただし、Requires =やWants =などの依存関係を使用した結果、または両方が一度に取得されていくつかの順序が定義された結果として、通常はジョブが存在します。この場合、別のユニットのジョブで待機します。