E-Bülten’e kayıt olun

E-Posta:



Supervisord vs Systemd

Supervisord vs Systemd

Supervisord geliştiriciler arasında epey ünlü ve başta Python tabanlı projeler olmak üzere pek çok geliştirici tarafından kullanılan bir işlem kontrol sistemi (process control system). Artistanbul yazılım ekibi olarak, Python ve PHP tabanlı projelerimizde Supervisord kullanıyor ve çok seviyoruz.

Ben de kişisel projelerimde işlem kontrolü için bu araca güveniyordum, ta ki her şeyden sorumlu müdürümüz Akın “Üşendim init script yazmadım demiyorsun da, bana Supervisor anlatıyorsun!” diye çıkışıp böyle bir bağımlılığa neden ihtiyaç duyduğumuzu sorgulatana kadar.

 

Supervisord’yi neden kullanıyoruz?

Genel anlamda bir işlem kontrol sistemi, özel anlamda Supervisord‘ye ihtiyaç duymamızın temelde iki nedeni var:

  1. Programın çökmesi ya da sistemin yeniden başlatılması halinde programın olabildiğince çabuk ayağa kalkması (başka bir ifade ile düşenin dostu olma özelliği).
  2. Programın işlemlerini tek tek veya hep birlikte durdurmak, başlatmak ve durumlarını kontrol etmek.

Supervisord bu iki iş için hem güvenilir hem de sade bir arayüz sunan, yapılandırması pek kolay bir araç olduğundan şu ana kadar birinci tercihimiz oldu. Peki, gerçekten de Akın’ın dediği gibi init script yazmaya mı üşeniyoruz?

 

Supervisord yerine systemd

Linux camiası systemd ile 2010 yılında tanıştı. Birçokları tarafından sevilmeyen ve Linux toplulukları içerisinde bolca tartışmaya yol açan bu yazılım şu anda RHEL/CentOS, Fedora, Debian ve Ubuntu tarafından init sistem olarak kabul edilmiş durumda. Şahsen dayattığı bazı değişiklikleri ben de sevmiyorum. Örneğin binary log dosyaları veya masaüstü çevreleri için kendini bir bağımlılık olarak kabul ettirmeye zorlaması hoşuma giden özellikler değil. Öte yandan şunu kabul etmek gerek ki, systemd büyük başlı bütün dağıtımlar tarafından kabul edilmiş durumda ve kalıcı. Dolayısıyla iyi taraflarını kendi yararımıza kullanmayı öğrenmek hepimiz için iyi olacaktır.

Akın’ın çıkışı beni supervisord yerine systemd kullanıp kullanamayacağımızı düşünmeye itti. Yukarıda saydığım bir işlem kontrol sisteminden beklediğimiz iki ana kullanım amacı systemd tarafından tam olarak karşılanabilir miydi?

systemd, işlem kontrolü için systemctl adlı komutu kullanıyor. Bunun için servisimiz için birim dosyası (unit file) denilen bir yapılandırma dosyası oluşturmamız gerekiyor. Bir Django uygulaması için örnek birim dosyası aşağıdaki gibi olabilir.


[Unit]
Description=Django uygulamam Mahmut
After=network.target

[Service]
User=mahmut
Group=mahmut
Environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8
ExecStart=/home/mahmut/bin/start

[Install]
WantedBy=multi-user.target

Yukarıda ilk bakışta anlaşılamayabilecek iki şey After ve WantedBy. After=network.target servisimizin ağ bağlantısı için gerekli birimler çalıştırıldıktan sonra çalıştırılmasını garantiliyor. Diğer bir özelliği ise sistem kapatılırken ağ bağlantısı servisleri kapatılmadan önce servisimizin kapatılması ve böylece kullanıcı tarafından yapılmış isteklerin yarıda kesilmemesinin sağlanması. WantedBy=multi-user.target ise sistem başlatıldığında servisimizin başlatılmasını sağlıyor.

Bu dosyayı /etc/systemd/system/mahmut.service olarak kaydettikten sonra servisimizi aşağıdaki komutlarla kontrol edebiliyoruz.


$ systemctl start mahmut
$ systemctl stop mahmut
$ systemctl restart mahmut
$ systemctl status mahmut

Aradığımız özelliklerin başında gelen düşenin dostu olma görevini systemd başarıyla uygulayabiliyor. Bunun için [Service] bölümüne Restart=always opsiyonunu eklemek gerekiyor. Restart opsiyonu always dışında değerler de kabul ediyor. Kullanılabilecek bütün değerleri görmek için bkz. systemd.service(5).

Bu noktada servisimizi durdurup başlatabiliyor, durumunu izleyebiliyor ve çökmesi halinde kendiliğinden ayağa kalkmasını sağlayabiliyoruz. Peki, diyelim ki Django’nun yanında bir de Celery çalıştırmak ve Django ile Celery servislerini hem tek tek hem de birlikte kontrol edebiliyor olmak istiyorum. systemd ile bunu da Supervisord kadar aşikâr olmasa da yapabiliyoruz.

systemd, grup kavramı yerine hedef (target) kavramını kullanıyor. Hedefler de birim dosyaları ile yapılandırılıyor ve birimleri gruplamak için kullanılıyor. Örneğin yukarıdaki örnek birim dosyamızda bulunan network.target ağ bağlantısı için gerekli servisleri gruplayan bir birim.

Mahmut adlı uygulamamız için bir hedef birim dosyası yazıp /etc/systemd/system/mahmut.target olarak kaydedelim.


[Unit]
After=network.target
Wants=mahmut.service mahmut_celery.service

[Install]
WantedBy=multi-user.target

Birim dosyalarımızı da buna uygun olarak aşağıdaki gibi değiştiriyoruz:


[Unit]
Description=Mahmut Celery
PartOf=mahmut.target

[Service]
User=mahmut
Group=mahmut
Environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8
ExecStart=/home/mahmut/bin/start_celery

Wants ve PartOf açıklanması gereken iki opsiyon. systemd.unit(5)‘e göre Wants ile listelenmiş birimler, hedef birim ayağa kalktığı anda ayağa kalkacak ama bu birimlerden biri ayağa kalkmakta başarısız olur ise bu işlemin bütününü etkilemeyecektir. Örnek olarak mahmut.target birimini başlattığımda, Django ve Celery servisleri başlayacak ancak bir sebeple Celery servisi başlayamazsa bu durum Django servisini çalışmasını engellemeyecek.

Aynı belgeye göre PartOf altında listelenmiş birimler ile hedef birim arasında bir bağımlılık ilişkisi oluşuyor ve hedef birimin başlatılması veya durdurulması gibi işlemler bu bağımlı birimlere de yansıyor. Öte yandan bu bağımlılık ilişkisi tek yönlü yani bağımlı birimlerin durdurulması veya başlatılması hedef birime yansımıyor. Bir örnek ile açıklayacak olursak, mahmut.target durdurulduğunda veya yeniden başlatıldığında Django ve Celery servisleri de durdurulacak veya yeniden başlatılacak. Üstelik Django servisinin yeniden başlatılması Celery servisini etkilemeyecek.

Nihayet hedef birime bağımlı birimleri list-dependencies komutu ile kontrol edebiliyorum. Soldaki nokta servisin durumuna göre yeşil ya da kırmızı görünüyor.


$ systemctl list-dependencies foo.target
foo.target
● ├─foo_django.service
● └─foo_celery.service

 

Sonuç

Supervisord kötüdür veya systemd daha iyidir demek istemiyorum. Supervisord bütün projelerimizde kullandığımız ve şu ana kadarki tecrübeme göre çok güvenilir bir uygulama. Ayrıca systemd‘nin sahip olmadığı kimi özelliklere de sahip, örneğin Supervisord ile servislerinizi web sunucu üzerinden de kontrol edebiliyorsunuz. Kullanım amacınız servislerinizin çalışmasını kontrol etmek ve sürekli çalıştığından emin olmak ise Supervisord gibi bir bağımlılığa ihtiyaç duyup duymadığınızı tekrar düşünebilirsiniz.

 

Bu yazının özgün hali kendi blogumda yayımlanmıştır.

Ege Güneş

Ege Güneş, İstanbul Üniversitesi Hukuk Fakültesi'nden mezun oldu. Günlük yaşamında özgür yazılımlardan yana ve Linux kullanıyor. Favori dağıtımıysa Fedora.

3 Yorumlar

Yorum Yaz

Yorum
İsim
E-Posta
Website