Systemd Restart = non è sempre rispettato


54

Nota: ho scritto un articolo su Medium che spiega come creare un servizio e come evitare questo particolare problema: la creazione di un servizio Linux con systemd .

Domanda originale:


Sto usando systemd per far funzionare sempre uno script di lavoro:

[Unit]
Description=My worker
After=mysqld.service

[Service]
Type=simple
Restart=always
ExecStart=/path/to/script

[Install]
WantedBy=multi-user.target

Sebbene il riavvio funzioni correttamente se lo script termina normalmente dopo alcuni minuti, ho notato che se non viene eseguito ripetutamente all'avvio, systemdsmetterà di provare ad avviarlo:

Jun 14 11:10:31 localhost systemd[1]: test.service: Main process exited, code=exited, status=1/FAILURE
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'exit-code'.
Jun 14 11:10:31 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.
Jun 14 11:10:31 localhost systemd[1]: test.service: Start request repeated too quickly.
Jun 14 11:10:31 localhost systemd[1]: Failed to start My worker.
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'start-limit'.

Allo stesso modo, se il mio script worker non riesce più volte con uno stato di uscita di 255, systemdrinuncia a provare a riavviarlo:

Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'exit-code'.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Start request repeated too quickly.  
Jun 14 11:25:51 localhost systemd[1]: Failed to start My worker.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Unit entered failed state.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'start-limit'.

C'è un modo per forzare systemda riprovare sempre dopo qualche secondo?

Risposte:


53

Vorrei estendere un po 'la risposta di Rahul.

SystemD tenta di riavviare più volte ( StartLimitBurst) e smette di provare se viene raggiunto il conteggio dei tentativi all'interno StartLimitIntervalSec. Entrambe le opzioni appartengono alla [unit]sezione.

Il ritardo predefinito tra le esecuzioni è 100ms ( RestartSec) che consente di raggiungere il limite di velocità molto rapidamente.

SystemD non tenterà mai più il riavvio automatico per le unità con il criterio di riavvio definito :

Notare che le unità configurate per Restart=e che raggiungono il limite di avvio non tentano più di essere riavviate; tuttavia, potrebbero essere riavviati manualmente in un secondo momento, da quel momento in poi la logica di riavvio verrà nuovamente attivata.

La risposta di Rahul aiuta, perché il ritardo più lungo impedisce di raggiungere il contatore degli errori nel StartLimitIntervalSectempo. La risposta corretta è però impostare entrambi RestartSece StartLimitBurstvalori ragionevoli.


5
Ora che (finalmente) capisco come funziona, dopo alcuni tentativi, posso vedere che la tua risposta è la più corretta. Linea di fondo per me: set StartLimitIntervalSec=0e voilà.
Benjamin,

35

, c'è. Puoi specificare di riprovare dopo alcuni xsecondi nella [Service]sezione,

[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/path/to/script

Dopo aver salvato il file, è necessario ricaricare le configurazioni del demone per assicurarsi che systemdsia a conoscenza del nuovo file,

systemctl daemon-reload

quindi riavviare il servizio per abilitare le modifiche,

systemctl restart test

Come da lei richiesto, guardando la documentazione,

Restart=on-failure

sembra una raccomandazione decente.


Sembra funzionare davvero, grazie! Quindi, per capirlo meglio, senza una RestartSecdirettiva, i systemdtentativi dei severals si riavvia molto rapidamente, quindi entra in uno stato di errore permanente; qualcosa che non può accadere quando RestartSecviene specificato?
Benjamin,

Inoltre, ho notato che ritarda il riavvio "normale" del mio lavoratore (dopo alcuni minuti esco intenzionalmente dal lavoratore); c'è un modo per ritardare solo un riavvio non riuscito ?
Benjamin,

@Benjamin guarda i miei aggiornamenti
Rahul,

@Benjamin puoi controllare qui per ulteriori parametri.
Rahul,

3
A giudicare dal documento , alwaysè un superset di on-failure, quindi non aiuterà!
Benjamin,

5

systemd rinuncia a provare a riavviarlo

No. systemd rinuncia a provare a riavviarlo per un po ' . Questo è chiaramente indicato nel registro che si fornisce:

14 giugno 11:25:51 localhost systemd [1]: test.service: errore con il limite di avvio .

Questa è la limitazione della velocità.

La durata del poco è specificata nell'unità di servizio, usando l' StartLimitIntervalSec=impostazione. Il numero di avviamenti necessari entro tale intervallo per attivare il meccanismo di limitazione della velocità viene specificato tramite l' StartLimitBurst=impostazione. Se nulla sul tuo sistema differisce da vanilla systemd, inclusi i valori predefiniti per queste due impostazioni, è 5 volte entro 10 secondi.

StartLimitIntervalSec=0disabilita il limite di velocità, quindi systemd riproverà per sempre piuttosto che arrendersi. Ma fare in modo che il tuo servizio non esca così spesso, o sia sufficientemente inattivo tra le uscite e i riavvii da non superare la soglia di limitazione della velocità, è un approccio migliore.

Tieni presente che il limite di velocità non importa come è uscito il tuo servizio. Si innesca il numero di tentativi di avvio / riavvio, indipendentemente dalla loro causa.

Ulteriori letture


5
Sembra rinunciare definitivamente, però: "Attivo: fallito (Risultato: limite di inizio) da mer 2016-06-15 01:21:24 CEST; 12h ago". Rimane in questo stato e lo script non viene mai più eseguito. Ho provato a impostare manualmente StartLimitIntervalSec=10e StartLimitIntervalSec=5, senza fortuna.
Benjamin,

5
Si arrende definitivamente per impostazione predefinita. Vedi github.com/systemd/systemd/issues/2416 .
Adam Goode,

2
Bottom line: per fermare, evitare che si arrenda definitivamente, impostare StartLimitIntervalSec=0.
Benjamin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.