systemd ile Kendi Servisinizi Yazmak: nohup Çağını Kapatmak

systemd ile Kendi Servisinizi Yazmak: nohup Çağını Kapatmak

Arka plan işçisini nohup ile başlatıp unutmak, sunucu yeniden başlayınca sessizce biten bir hizmet demektir.

Kuyruk işçisi, planlanmış görev çalıştırıcısı veya küçük bir arka plan servisi yazdınız. Onu nohup ... & ile başlattığınızda çalışır — ta ki sunucu yeniden başlayana, süreç çökene veya biri terminali kapatana kadar. systemd servisi tanımlamak bu üç riski birden ortadan kaldırır ve on satırlık bir dosyadan ibarettir.

nohup ve systemd karşılaştırması
Bir işçinin çalıştığını bilmek, onu başlatmaktan daha önemlidir.

Minimum çalışan unit dosyası

INI
# /etc/systemd/system/mail-isci.service
[Unit]
Description=Mail kuyruğu işçisi
After=network-online.target mysql.service
Wants=network-online.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/uygulama/canli
ExecStart=/usr/bin/php spark mail:work --daemon

# Çökerse her zaman yeniden başlat, ama sonsuz döngüye girme
Restart=always
RestartSec=5
StartLimitIntervalSec=300
StartLimitBurst=5

# Kaynak sınırı: kaçak bir işçi sunucuyu tüketmesin
MemoryMax=512M
CPUQuota=50%

# Günlükler journald'a düşsün (dosya yönetimiyle uğraşmayın)
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mail-isci

[Install]
WantedBy=multi-user.target
Bash
sudo systemctl daemon-reload
sudo systemctl enable --now mail-isci
systemctl status mail-isci

Üç alan, üç ders

Restart ve StartLimitBurst birlikte kullanılır

Yalnızca Restart=always yazarsanız, başlangıçta hata veren bir servis saniyede defalarca yeniden başlar ve sunucuyu yorar. StartLimitBurst, 5 dakikada 5 başarısız denemeden sonra durmasını sağlar — böylece gerçek bir sorun sessizce gizlenmez, görünür hâle gelir.

MemoryMax bir sigortadır

PHP tarafında bellek sızdıran uzun ömürlü bir işçi, zamanla tüm belleği tüketip veritabanını dışarı itebilir. Sınır koymak, en kötü senaryoyu tek servise hapseder. Uzun ömürlü işçilerde ayrıca belirli sayıda işten sonra sürecin kendini sonlandırması (ve systemd'nin onu yeniden başlatması) yaygın ve sağlıklı bir desendir.

After bir garanti değildir

After=mysql.service yalnızca başlatma sırasını belirler; MySQL'in bağlantı kabul etmeye hazır olduğunu garanti etmez. Bu yüzden uygulama tarafında da yeniden deneme mantığı bulunmalıdır.

Günlükleri okumak

Bash
# Canlı takip
journalctl -u mail-isci -f

# Son 100 satır, zaman damgalı
journalctl -u mail-isci -n 100 --no-pager

# Yalnızca hatalar, son 24 saat
journalctl -u mail-isci -p err --since "24 hours ago"

# Servis kaç kez yeniden başlamış? (sessiz çökmelerin izi)
systemctl show mail-isci -p NRestarts

NRestarts değeri, hiçbir alarm kurmadığınız durumda bile sessiz çökmeleri ortaya çıkarır. Günlüklerde zaman dilimi karışıklığı yaşıyorsanız sunucu loglarında zaman dilimi tuzağı yazımız doğrudan bu konuyu ele alıyor. Neyin loglanacağı konusunda ise üretimde log'a ne yazmalı yazımız pratik bir çerçeve sunuyor.

cron yerine systemd timer

Zamanlanmış görevler için timer, cron'a göre üç avantaj sunar: görev çıktısı journald'a düşer, kaçırılan çalıştırmalar telafi edilebilir ve servis birimiyle aynı kaynak sınırlarını devralır.

INI
# /etc/systemd/system/blog-yayin.timer
[Unit]
Description=Zamanlanmış blog yazılarını yayına alır

[Timer]
OnCalendar=*:0/5              # her 5 dakikada bir
Persistent=true               # sunucu kapalıyken kaçırılanı açılışta çalıştır
AccuracySec=30s

[Install]
WantedBy=timers.target
Bash
systemctl list-timers --all    # sıradaki çalıştırma zamanlarını gösterir

Timer ve servis dosyaları aynı adı taşımalıdır (blog-yayin.timerblog-yayin.service); systemd eşleşmeyi ada göre yapar. Farklı bir servisi tetiklemek isterseniz Unit= alanını açıkça yazın.

Sunucu kurulumunun ilk adımlarını Linux sunucu kurulumu yazımızda toplamıştık; systemd birimleri bu listenin doğal devamıdır. Birim dosyası alanlarının tam listesi için systemd.service kılavuz sayfası nihai kaynaktır.

Sonuç

Arka plan işçisini başlatmak kolaydır; asıl iş onun çalıştığından emin olmaktır. systemd bunu üç şeyi birden vererek çözer: açılışta otomatik başlatma, çökme sonrası kontrollü yeniden başlatma ve merkezî günlükleme. Yazacağınız unit dosyasında Restart ile StartLimitBurst'ü birlikte tanımlayın, bellek sınırı koyun ve NRestarts sayacını düzenli kontrol edin. Sunucunuzda hâlâ nohup ile başlatılmış bir süreç varsa, bir sonraki yeniden başlatmada onu kaybedeceksiniz — bugün on satırlık bir dosyayla bu riski kapatabilirsiniz.

Pratik Uygulama Kontrol Listesi

Bu yazıdaki önerileri kendi ekibinize uyarlarken aşağıdaki adımları sırasıyla uygulamanız, teoriden pratiğe geçişi kolaylaştırır:

  1. Mevcut durumu ölçün. Değişiklik yapmadan önce bugünkü performansı/süreyi/hata oranını kaydedin; aksi halde iyileşmeyi kanıtlayamazsınız.
  2. Küçük bir pilot seçin. Tüm sisteme veya tüm ekibe birden uygulamak yerine tek bir modülde veya tek bir sprintte deneyin.
  3. Sonuçları ekiple paylaşın. Elde ettiğiniz veriyi (olumlu ya da olumsuz) kısa bir notla ekibe aktarın; kararın gerekçesi belgelenmemişse aynı tartışma birkaç ay sonra tekrar açılır.
  4. Süreci tekrarlanabilir hale getirin. İşe yarayan pratiği bir kontrol listesine veya şablona dönüştürün ki yeni katılan ekip üyeleri de aynı standardı hızlıca öğrensin.

Systemd Servisi konusunda attığınız her küçük adım ölçülebilir olduğu sürece değerlidir; büyük ve tek seferlik dönüşümler yerine sürekli, küçük iyileştirmeler uzun vadede daha kalıcı sonuç verir.

Sık Yapılan Yanlışlar

Bu konuda ekiplerin en çok düştüğü tuzak, çözümü tek bir kişiye ya da tek bir araca yüklemektir. Oysa kalıcı iyileşme, sürecin ekibin günlük rutinine (code review kontrol listesi, sprint planlama, onboarding dokümanı gibi) gömülmesiyle mümkün olur. İkinci yaygın hata ise "en iyi pratiği" olduğu gibi kopyalamaktır — başka bir ekipte işe yarayan bir yaklaşım, farklı bir ölçekte veya farklı bir teknoloji yığınında aynı sonucu vermeyebilir; önce kendi bağlamınızda küçük ölçekte test edin, sonra genişletin. Üçüncü tuzak ise ölçmeden karar vermektir: "daha iyi hissettiriyor" öznel bir gerekçedir, ekip içi tartışmalarda nesnel veriyle desteklenmeyen kararlar er ya da geç sorgulanır ve geri alınır. Son olarak, dokümantasyonu atlamak da sık görülen bir hatadır: bir kararın "neden" alındığı yazılı değilse, ekip altı ay sonra aynı tartışmayı sıfırdan yeniden yapmak zorunda kalır ve önceki deneyimden öğrenilenler kaybolur.

Sonuç

systemd ile Kendi Servisinizi Yazmak: nohup Çağını Kapatmak konusunda burada değindiğimiz noktalar, konuyu ilk kez ele alan ekipler için de deneyimli geliştiriciler için de pratik bir kontrol listesi görevi görür. systemd servisi üzerine çalışırken en çok fayda sağlayan yaklaşım, tek seferde her şeyi mükemmelleştirmeye çalışmak yerine küçük, ölçülebilir adımlarla ilerlemektir. Ekibinizde bu konuyu bir sonraki sprint retrospektifinde veya teknik tartışma toplantısında gündeme getirmenizi, burada anlatılan pratiklerden hangilerinin sizin bağlamınıza uyduğunu birlikte değerlendirmenizi öneririz. Sonuç olarak, doğru araçları seçmek kadar bunları ekip kültürüne oturtmak da başarıyı belirleyen asıl etkendir.

Beğeniniz benzer içerikleri öne çıkarmamıza yardımcı olur.

Sık Sorulan Sorular

simple, ExecStart ile başlatılan sürecin ana süreç olarak kalacağını varsayar; modern uygulamaların çoğu böyledir. forking ise sürecin arka plana geçip ana sürecin sonlanacağı klasik daemon davranışı içindir. Yanlış tip seçimi, systemd'nin servisi başlamış ya da ölmüş sanmasına yol açar.

Süreç durumu yeterli bir sağlık göstergesi değildir. İşçinin düzenli olarak bir "kalp atışı" yazması (son işlem zamanı, işlenen kayıt sayısı) ve bu değeri izlemeniz gerekir. systemd sürecin ayakta olduğunu bilir, faydalı iş yaptığını bilemez.

Küçük değerler için Environment= satırı, sır içeren değerler için EnvironmentFile= ile ayrı bir dosya kullanın. Sır dosyasının izinlerini sıkı tutun (0600) ve depoya asla eklemeyin; unit dosyası genelde herkes tarafından okunabilir durumdadır.

Zorunlu değil. Basit ve kısa görevlerde cron hâlâ pratiktir. Ancak görev uzun sürüyorsa, kaynak sınırı gerekiyorsa veya çıktısını izlemek istiyorsanız timer belirgin biçimde daha iyi bir araçtır. İkisini karıştırmamak, hangi görevin nerede tanımlı olduğunu bulmayı kolaylaştırır.

S
superadmin

Bu yazıyı hazırladı. Sorularınız için iletişim sayfasından ulaşabilirsiniz.

Yorumlar (0)

Bu yazıya henüz yorum yapılmamış. İlk yorumu siz yazın!

Yorum Yaz

Yorumunuz onaylandıktan sonra yayınlanır. Ekibimiz gerekirse konuyla ilgili bir yanıt da paylaşır.

En az 10 karakter.