전략

전략

~에 대한체계, 다른 서비스가 실행되는 동안 실행 중인 서비스를 일시 중지하거나 중지할 수 있습니까(모든 데이터가 기록되었는지 확인)?

내 시나리오는 다음과 같습니다. 센서를 구축했습니다(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위의 세 줄을 처리하는 유닛입니다.

답변1

귀하의 질문에 작성한 스크립트에 작은 문제가 있습니다. compute.service시작하기 전에 멈출 때까지 기다리지 않습니다 sensor.service.


전략

다음은 네 가지 전략입니다. 제 생각에는 세 번째가 제가 가장 좋아하는 것 같아요.

동시성을 수행하는 다른 방법 찾기

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해결되지 않았지만 최소한 이를 줄이고 더 투명하게 만들었습니다(스크립트에 숨기지 않고).

타이머 두 개

약간 촌스럽기는 하지만 줄을 바꾸고 싶다면 ExecStopPost=타이머를 두 개 사용할 수 있습니다. compute.timer이미 하고 있는 것처럼 원하는 만큼 자주 계산하도록 설정합니다. 5분의 데이터를 계산하려면 트리거 5분 전부터 시작하도록 설정하세요 sensor.timer.sensor.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

답변2

내 문제를 해결하기 위해 지금까지 찾은 모범 사례는 다른 질문에 설명되어 있습니다.https://unix.stackexchange.com/a/318744/208465

관련 정보