Reinicio del sistema = siempre no se cumple

54

Nota: Escribí un artículo en Medium que explica cómo crear un servicio y cómo evitar este problema en particular: Crear un servicio de Linux con systemd .

Pregunta original


Estoy usando systemd para mantener un script de trabajo funcionando en todo momento:

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

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

[Install]
WantedBy=multi-user.target

Aunque el reinicio funciona bien si el script sale normalmente después de unos minutos, he notado que si falla repetidamente en el inicio, systemdsimplemente dejará de intentar iniciarlo:

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'.

Del mismo modo, si mi script de trabajo falla varias veces con un estado de salida de 255, systemddeja de intentar reiniciarlo:

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'.

¿Hay alguna forma de forzar systemda volver a intentar siempre después de unos segundos?

Benjamín
fuente

Respuestas:

53

Me gustaría extender un poco la respuesta de Rahul.

SystemD intenta reiniciarse varias veces ( StartLimitBurst) y deja de intentarlo si se alcanza el recuento de intentos dentro StartLimitIntervalSec. Ambas opciones pertenecen a la [unit]sección.

El retraso predeterminado entre ejecuciones es de 100 ms ( RestartSec), lo que hace que el límite de velocidad se alcance muy rápido.

SystemD no intentará más reinicios automáticos para unidades con la política de reinicio definida :

Tenga en cuenta que las unidades que están configuradas Restart=y que alcanzan el límite de inicio ya no se intentan reiniciar; sin embargo, aún pueden reiniciarse manualmente en un punto posterior, a partir de ese momento, la lógica de reinicio se activa nuevamente.

La respuesta de Rahul ayuda, porque el retraso más largo impide alcanzar el contador de errores dentro del StartLimitIntervalSectiempo. La respuesta correcta es establecer tanto RestartSecy StartLimitBurstcon los valores razonables sin embargo.

MarSik
fuente
55
Ahora que (finalmente) entiendo cómo funciona, después de una prueba y error, puedo ver que su respuesta es la más correcta. En pocas palabras para mí: set StartLimitIntervalSec=0y voilà.
Benjamin
35

Sí lo hay Puede especificar volver a intentar después de xsegundos en la [Service]sección,

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

Después de guardar el archivo, debe volver a cargar las configuraciones de daemon para asegurarse de systemdconocer el nuevo archivo,

systemctl daemon-reload

luego reinicie el servicio para habilitar los cambios,

systemctl restart test

Como ha solicitado, mirando la documentación,

Restart=on-failure

Suena como una recomendación decente.

Rahul
fuente
Parece funcionar de hecho, ¡gracias! Entonces, para comprender esto mejor, sin una RestartSecdirectiva, systemdintenta varios reinicios muy rápidamente, luego entra en un estado de falla permanente; algo que no puede suceder cuando RestartSecse especifica?
Benjamin
Además, me di cuenta de que retrasa el reinicio "normal" de mi trabajador (después de unos minutos salgo con gracia del trabajador); ¿Hay alguna manera de retrasar solo un reinicio fallido ?
Benjamin
@Benjamin mira mis actualizaciones
Rahul
@Benjamin puedes consultar aquí para más parámetros.
Rahul
3
A juzgar por el documento , alwayses un superconjunto de on-failure, por lo que no ayudará.
Benjamin
5

systemd deja de intentar reiniciarlo

No. systemd deja de intentar reiniciarlo por un tiempo . Esto se muestra claramente en el registro que proporciona:

14 de junio 11:25:51 localhost systemd [1]: test.service: error con el resultado 'start-limit' .

Esto es patada limitante de velocidad.

La duración del momento se especifica en la unidad de servicio, utilizando la StartLimitIntervalSec=configuración. El número de arranques que se necesitan dentro de ese intervalo para activar el mecanismo de limitación de velocidad se especifican a través de la StartLimitBurst=configuración. Si nada en su sistema difiere de vanilla systemd, incluidos los valores predeterminados para estas dos configuraciones, entonces es 5 veces en 10 segundos.

StartLimitIntervalSec=0desactiva la limitación de velocidad, por lo que systemd volverá a intentarlo para siempre en lugar de darse por vencido. Pero hacer que su servicio no salga con tanta frecuencia o que esté lo suficientemente inactivo entre salidas y reinicios como para que no exceda el límite de límite de velocidad, es un mejor enfoque.

Tenga en cuenta que a la limitación de velocidad no le importa cómo salió su servicio. Se dispara con la cantidad de intentos de iniciarlo / reiniciarlo, independientemente de su causa.

Otras lecturas

JdeBP
fuente
55
Sin embargo, parece darse por vencido permanentemente: "Activo: fallido (Resultado: límite de inicio) desde el miércoles 15/06/2016 01:21:24 CEST; hace 12 horas". Permanece en este estado y el script nunca se ejecuta nuevamente. Intenté configurarlo manualmente StartLimitIntervalSec=10y StartLimitIntervalSec=5, sin suerte.
Benjamin
55
Se da por vencido de forma permanente por defecto. Consulte github.com/systemd/systemd/issues/2416 .
Adam Goode
2
En pocas palabras: para evitar que se rinda permanentemente, configure StartLimitIntervalSec=0.
Benjamin