Systemd Restart = her zaman onurlandırılmaz


53

Not: Medium'da nasıl bir hizmet oluşturulacağını ve bu özel sorunun nasıl önlenebileceğini açıklayan bir makale yazdım: systemd ile Linux hizmeti oluşturma .

Orijinal soru:


Bir çalışan betiğini her zaman çalışır durumda tutmak için systemd kullanıyorum:

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

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

[Install]
WantedBy=multi-user.target

Her ne kadar komut dosyası birkaç dakika sonra normal bir şekilde çıkarsa, yeniden başlatma düzgün çalışsa da, başlangıçta tekrar tekrar yürütülememesi durumunda, başlatmaya systemdçalışmaktan vazgeçeceğini fark ettim :

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

Benzer şekilde, çalışan betiğim çıkış durumuyla birkaç kez başarısız olursa 255, systemdyeniden başlatmayı denemekten vazgeçer:

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

Zorlamak için bir yolu var mı systemdetmek her zaman bir kaç saniye sonra tekrar deneyin?

Yanıtlar:


53

Rahul'un cevabını biraz uzatmak istiyorum.

SystemD birden çok kez ( StartLimitBurst) yeniden başlatmayı dener ve içinde deneme sayısına ulaşılırsa denemeyi durdurur StartLimitIntervalSec. Her iki seçenek de [unit]bölüme aittir .

İşlemler arasındaki varsayılan gecikme 100ms'dir ( RestartSec), hız limitine çok hızlı ulaşılmasını sağlar.

SystemD, yeniden başlatma ilkesi tanımlanmış birimler için hiç otomatik yeniden başlatma girişiminde bulunmayacak :

Artık yapılandırılmış Restart=ve başlangıç ​​limitine ulaşmış olan ünitelerin artık yeniden başlatılmaya çalışılmadığını unutmayın; ancak, daha sonra manuel olarak yeniden başlatılabilirler, bu noktadan itibaren yeniden başlatma mantığı tekrar etkinleştirilir.

Rahul'un cevabı yardımcı oluyor, çünkü daha uzun gecikme StartLimitIntervalSeczaman içerisinde hata sayacına ulaşmayı engelliyor . Doğru cevap, hem ayarlamaktır RestartSecve StartLimitBurstolsa makul değerlere.


5
Şimdi (nihayet) nasıl çalıştığını anladığım için, bazı deneme yanılmalardan sonra cevabınızın en doğru olduğunu görebiliyorum. Benim için alt satır: set StartLimitIntervalSec=0ve voilà.
Benjamin

34

Evet var. Bölümün xaltındaki saniye sonunda tekrar denemeyi belirleyebilirsiniz.[Service]

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

Dosyayı kaydettikten sonra systemd, yeni dosyanın farkında olduğundan emin olmak için arka plan programı yeniden yüklemeniz gerekir.

systemctl daemon-reload

ardından değişiklikleri etkinleştirmek için servisi yeniden başlatın.

systemctl restart test

İstediğiniz gibi, belgelere bakmak,

Restart=on-failure

iyi bir öneri gibi geliyor.


Gerçekten çalışıyor gibi görünüyor, teşekkür ederim! Dolayısıyla, bunu daha iyi anlamak için, bir RestartSecdirektif olmadan , systemdbirkaçın çok hızlı bir şekilde yeniden başlatılmasını dener, ardından kalıcı bir başarısızlık durumuna girer; bir şey olduğunu olamaz zaman ne RestartSecbelirtildi?
Benjamin

Ayrıca, çalışanımın "normal" yeniden başlatılmasını geciktirdiğini fark ettim (birkaç dakika sonra çalışmayı zarif bir şekilde bırakıyorum); başarısız bir yeniden başlatmayı yalnızca geciktirmenin bir yolu var mı?
Benjamin

@Benjamin güncellemelerimi gör
Rahul

@ Benjamin daha fazla parametre için burada kontrol edebilirsiniz .
Rahul,

3
Bakılırsa doc , alwaysbir üst kümesidir on-failure, bu yüzden yardımcı olmaz!
Benjamin

5

systemd yeniden başlatmaya çalışırken pes

No. systemd, bir süre için yeniden başlatmaya çalışmaktan vazgeçer . Bu, girdiğiniz kayıt defterinde açıkça gösterilir:

Jun 14 11:25:51 localhost systemd [1]: test.service: 'start-limit' ile sonuçlanmadı .

Bu tekmeleme oranı sınırlama.

Küçük süre uzunluğu, servis birimi tarafından StartLimitIntervalSec=ayar kullanılarak belirlenir. Hız sınırlama mekanizmasını tetiklemek için bu aralıkta gerekli olan başlangıç ​​sayısı StartLimitBurst=ayar aracılığıyla belirlenir. Sisteminizde hiçbir şey bu iki ayarın varsayılanları dahil olmak üzere vanilya sisteminden farklı değilse, o zaman 10 saniye içinde 5 defadır.

StartLimitIntervalSec=0Hız sınırlamayı devre dışı bırakır, böylece sistem pes etmek yerine sonsuza dek yeniden dener. Ancak, hizmetinizin çok sık çıkmaması ya da çıkışlar ve yeniden başlatmalar arasında hız sınırlama eşiğini geçmeyecek kadar boşta kalması daha iyi bir yaklaşımdır.

Ücret sınırlamasının servisinizden nasıl çıkıldığını önemsemediğini unutmayın. Sebeplerinden bağımsız olarak, onu başlatma / yeniden başlatma girişimlerinin sayısını tetikler.

daha fazla okuma


5
Yine de kalıcı bir şekilde vazgeçmiş görünüyor: "Aktif: başarısız oldu (Sonuç: başlangıç ​​sınırı) Çar 2016-06-15 01:21:24 CEST; 12 saat önce". Bu durumda kalır ve senaryo bir daha asla çalıştırılmaz. Manuel olarak ayarlamayı denedim StartLimitIntervalSec=10ve StartLimitIntervalSec=5şansım yok.
Benjamin

5
Varsayılan olarak kalıcı olarak pes eder. Bakınız github.com/systemd/systemd/issues/2416 .
Adam Goode,

2
Alt satır: kalıcı olarak vazgeçmesini önlemek için ayarlayın StartLimitIntervalSec=0.
Benjamin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.