戦略

戦略

~についてシステム、他のサービスの実行中に実行中のサービスを一時停止または停止できますか(すべてのデータが記録されていることを確認)。

私のシナリオは次のとおりです。センサーを構築しました(Raspberry Pi Zero WベースとKali Linuxを実行)。認識に使用されるデーモンは、sensor.service起動プロセスが完了した直後に起動されます(システムサービス単位で)。

[Unit]
Description=Arbitrary sensor
After=network.target

[Service]
ExecStart=/usr/local/bin/sense --daemon

[Install]
WantedBy=multi-user.target

センサーは常にローカルでデータを収集して保存します。データは定期的に計算され、結果はネットワークを介して送信されます。今計算するときすべてのデータが記録されていることを確認するには、センサーからのデータの受信を中断する必要があります。、計算が始まる前に。計算が完了したら、センサーは追加のデータ収集を開始する必要があります。

はい、この問題を処理するためにスクリプトを直接作成できます。

systemctl stop sensor.service
systemctl start compute.service  # Terminates itself
systemctl start sensor.service

しかし、これがsystemdが私のために処理できるシナリオかどうか疑問に思います。特にスクリプトを直接書く必要はありません。私が想像するのは、compute.timer上記の3行を処理するユニットです。

ベストアンサー1

あなたの質問に書いたスクリプトに小さな問題があります。compute.service始める前に停止するのを待ちませんsensor.service


戦略

以下は4つの戦略です。私の考えでは、3番目は私が一番好きだと思います。

並行性を実行する別の方法を見つける

sensor.service停止する必要があるかどうかわかりません。これを行う理由は、新しいデータが計算に影響を与えないためです。この場合、データファイルのスナップショットを撮ります。その後、そのスナップショットに基づいて計算が行われます。このスナップショットは計算中に更新されないため、並行性の問題が解決されます。使用することは、サービスが停止したときに削除される新しい一時インストールを効果的にインポートすることをPrivateTmp=意味します。/tmp

# /etc/systemd/system/compute.service
[Service]
ExecStartPre=/bin/cp /var/lib/sensor/data /tmp/data_to_compute
ExecStart=/usr/bin/compute /tmp/data_to_compute
PrivateTmp=yes

時間のあるスクリプトですべての作業を行います。

本当にsensor.serviceを停止する必要がある場合、スクリプトのアイデアも悪くありません。おそらく次の内容compute.timercompute.service含まれますExecStart=/usr/local/bin/compute.sh

#!/bin/sh
systemctl stop sensor.service
/usr/bin/compute /var/lib/sensor/data
systemctl start sensor.service

システム関係の使用

前の例では、systemctlsystemd が実行するスクリプト内で呼び出しを行いました。何か間違っていると思います。 systemd の関係は、Conflicts=サービスの開始時に競合するサービスが自動的に停止することを意味します。 systemdは、他のプロセスが完了したときにプロセスを開始することとは関係がないため、ExecStartPost=ここで使用できます。

したがって、次の項目に追加してくださいcompute.service

[Unit]
Conflicts=sensor.service

[Service]
ExecStart=/usr/bin/compute /var/lib/sensor/data
ExecStopPost=systemctl start sensor.service

sensor.serviceトリガーしたら、停止したい目標を達成しますcompute.timer。カスタムシェルスクリプトの代わりにすべてをユニットファイルに移動しました。 systemd内で使用したときに発生する不快感の問題はsystemctl解決されませんでしたが、少なくともこれを減らして透明性を高めました(スクリプトに隠すことなく)。

2つのタイマー

ちょっととんでもないですが、行を変更したい場合は、2つのExecStopPost=タイマーを使用できます。 compute.timerすでにやっているように、必要に応じて頻繁に計算するように設定します。 5分のデータを計算するには、トリガーの5分前から開始するように設定しますsensor.timersensor.servicecompute.timer


それらを一つにまとめる

どの戦略を使用してもcompute.timer心の平和が必要ですcompute.serviceが、接触は必要ありませんsensor.service。私はあなたがシステムタイマーを作る方法を尋ねたかもしれないことを知っています。戦略3を全体的に実装する方法は次のとおりです。

# /etc/systemd/system/compute.timer
[Unit]
Description=Timer to trigger computations every 15 minutes

[Timer]
OnCalendar=*:0/15

[Install]
WantedBy=timers.target

compute.timercompute.service(上)は15分ごとに始まります(下)。

# /etc/systemd/system/compute.service
[Unit]
Description=Runs computation (triggered by compute.timer)
Conflicts=sensor.service

[Service]
ExecStart=/usr/bin/compute /var/lib/sensor/data
ExecStopPost=systemctl start sensor.service

次にタイマーを有効にします(または再起動したくない場合はタイマーを起動します)。

systemctl enable compute.timer
systemctl start compute.timer

おすすめ記事