Systemd'deki basit tip hizmetler için neden "süreç çatallanmamalıdır"?
systemd
Gerçekten uzun çalışan komutları 1 (saat sırasıyla) yönetmek için kendi birim dosyalarımı yazmak istiyorum . Systemd ile ilgili ArchWiki makalesine bakarken, bir başlangıç türü seçmekle ilgili olarak şunları söylüyor:
Type=simple
(varsayılan): systemd, hizmetin hemen başlatılacağını düşünür. Süreç çatallanmamalıdır . Bu hizmette başka hizmetlerin sipariş edilmesi gerekiyorsa, soket etkinleştirilmediği sürece bu türü kullanmayın.
Süreç neden çatallanmamalı? Artalan süreci çağırma süreci (ana çatallar, sonra çıkışlar) tarzında çatallanmaya mı yoksa herhangi bir tür çatallanmaya mı atıfta bulunuyor?
1 tmux / screen istemiyorum çünkü durumu kontrol etmenin ve hizmeti başvurmadan yeniden başlatmanın daha zarif bir yolunu istiyorum tmux send-keys
.
Yanıtlar
Servisin fork
sistem çağrısını aramasına izin verilir . Systemd bunu engellemeyecek veya önlediğini fark etmeyecektir. Bu cümle, özellikle deemon'u ana sürecinden izole etmek için bir arka plan programının başlangıcında çatallanma uygulamasına atıfta bulunmaktadır. "Süreç çatallanmamalı [ve hizmeti bir alt süreçte çalıştırırken üst süreçten çıkmamalıdır]”.
Adam sayfa daha verbosely bu açıklar ve bu özel karışıklığa yol açmaz bir ifade ile.
Arka plan programı olarak kullanılması amaçlanan birçok programın, başladıklarında kendilerini ebeveynlerinden izole ettikleri bir moda (genellikle varsayılan mod) sahiptir. Arka plan programı başlar, çağırır fork()
ve ebeveyn çıkar. Alt süreç setsid()
, kendi süreç grubu ve oturumunda çalışması için çağırır ve hizmeti çalıştırır. Amaç, arka plan programı bir kabuk komut satırından çalıştırılırsa, uçbirime kapanma gibi bir şey olsa bile, arka plan programının çekirdekten veya kabuktan herhangi bir sinyal almayacağıdır (bu durumda kabuk SIGHUP gönderir bildiği tüm süreç gruplarına). Bu aynı zamanda hizmet sürecinin init tarafından benimsenmesine neden olur, bu da çıktığında onu alır , arka plan programı kendisi için olmayacak bir şeyle başlatılmışsa bir zombiden kaçınır wait()
(arka plan programı bir kabuk tarafından başlatılmışsa bu olmazdı) ).
Bir arka plan programı systemd gibi bir izleme süreci tarafından başlatıldığında, çatallanma ters etki yaratır. İzleme sürecinin, çökmesi durumunda hizmeti yeniden başlatması gerekir, bu nedenle hizmetin çıkıp çıkmadığını bilmesi gerekir ve hizmet, izleme sürecinin doğrudan bir alt öğesi değilse bu zordur. İzleme sürecinin asla ölmemesi ve bir kontrol terminali olmaması, bu nedenle istenmeyen sinyaller veya biçme konusunda endişeler yoktur. Bu nedenle, hizmet sürecinin monitörün çocuğu olmaması için hiçbir neden yoktur ve olması için iyi bir neden vardır.
Bu Arch wiki sayfasını yoksayın.
Ortamla ilgili olarak oldukça yanlış şeyler var Type
. simple
Üstelik bu sadece açıklamaları ile sınırlı değildir . Hakkında söylediği forking
de yanlış.
Bu tür şeyler için doğru öneriler, systemd'nin kendisinin var olduğundan on yıllardır mevcuttur ve en azından 1990'ların başına kadar uzanmaktadır. Dediğim gibihttps://unix.stackexchange.com/a/476608/5132, systemd doco'da, daemontools kullanıcıları, IBM, insanlar kullandıklarını inittab
ve… şey… Ben on yıllardır söylüyorum , dæmons için tavsiyelerin Johnny'nin son zamanlarda geldiği bir versiyonu var. (2001'de böyle yazdığımda zaten sıkça verilen bir cevaptı.)
Tekrarlamak için:
Programınızda özellikle bir çocuğu çatallayan ve üst süreçten çıkan bir "dæmonization" mekanizması varsa, onu kapatın ve kullanmayın . Daemontools ve ark. bunun uzun süredir bir gereklilik olduğu yerlerde, birçok program son 20 yıldan fazla bir süredir bu tür mekanizmalara sahip olmama becerisini geliştirmiştir ve diğerleri, ilk etapta "dæmonizing" seçeneğini varsayılan olarak kullanmadığından, varsayılan çalışma modları.
Servis yönetimi alt sistemleri, servis süreçlerini zaten dæmon bağlamında başlatmaktadır . Bu süreçlerin "dæmonize" etmesine gerek yoktur. (Gerçekten de, programların bir oturum açma bağlamından "dæmonize" edebileceğini düşünmek birçok modern işletim sisteminde bir yanlıştır , ki bu aslında "dæmonization" ile ilgilidir.) Zaten ortam değerlerine ve açık dosya tanımlayıcılarına sahiptirler, Daemon bağlama uygun ve aslında "dæmonization" tarafından yapılan birkaç şey önlemek düzenli servis yöneticileri tarafından (bir günlüğüne örneğin yakalama kendi standart çıkışlar / hataları) daemons ile yapılır geleneksel bazı şeyleri.
Tercih Type=simple
(hizmet yönetim sunucusu yuva açar ve servis programına zaten açık dosya tanımlayıcıları olarak iletir) erken soket açılmasıyla veya Type=notify
.
Type=simple
Servis istemcilerini geciktirmek için soket bağlantı anlamlarını kullanan erken soket açılışıyla, hizmet süreci başlar başlamaz, hizmete hazır olarak davranır (böylece hizmet siparişi başlatılabilir / durdurulabilir), sunuculara bağlanmaya çalıştıkları noktalarda hizmet, sunucular gerçekten hazır olana kadar.Type=notify
sisteme ve Linux'a özgü olma dezavantajına sahiptir (kabuk yumurtlama gibi kısa ömürlü süreçlerden işlevsel olmama sorunlarının yanı sıra vesystemd-notify
ayrıcalıklı bir süreçte insan tarafından okunabilir formların makine tarafından okunabilir biçimlere ayrıştırılmasını kullanma sorunlarının yanı sıra ayrıştırıcı sorunları geçmişte zaten olmuştur), ancak hizmetin gerçekten ne zaman hazır olduğu konusunda daha iyi kontrol (hizmet programı açısından) sağlama avantajına sahiptir. Ayrıca durum çıktısının bazı özelleştirmelerine izin verir.
Her iki tipteki servis programları çatallanabilir. Çatallanma ve ardından asıl sorun olan süreçten çıkılıyor .
(Unutulmamalıdır ki, bu, programları kabuklardan çalıştırmak kadar, program yöneticilerinin programlarını çalıştırmak için olduğu kadar, kullanıcıların programların hemen sonlandığını ve başka bir kabuk istemine neden olduğunu görmesi için de bir problemdir. , çatallayıp ebeveynden çıkan programların kabuktan çalıştırılması hakkında, Neden bazen bir programı terminalde çalıştırdığımda terminalde çalışmıyor? )
Type=oneshot
muhtemelen bu özel durumda istediğiniz şey değildir, çünkü hizmet yalnızca tüm hizmet programı tamamlanana kadar çalıştığında hazır kabul edilir. Kullanımları vardır, ancak kulağa göre bunlar sizin için geçerli değildir.
Asla kullanma Type=forking
. Neredeyse hiçbir program protokolü gerçekten konuşmadığından, bu son çare olmalıdır . Aslında bu protokol olmayan, bu protokolle doğru şekilde birlikte çalışmayan ve aslında hazır olduğunun sinyalini vermeyen başka bir şey yapıyorlar .
daha fazla okuma
- Jonathan de Boyne Pollard (2001). Unix dæmon programlarını tasarlarken kaçınılması gereken hatalar . Sık Verilen Cevaplar.
- Jonathan de Boyne Pollard (2015). Gerçekten deemonize etmenize gerek yok. Gerçekten mi. . Sistemdeki Korku Evi.
- Jonathan de Boyne Pollard (2015). Unix dæmons ile hazırlık protokolü sorunları . Sık Verilen Cevaplar.
- https://unix.stackexchange.com/a/401611/5132