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:
- 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).
- 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.
Zafer
Faydalandığım bir yazı oldu teşekkürler. Biz de systemd yerine supervisor’a gerek var mı diyerek yola çıktık. Deneyiminizden anladığım web tabanlı arayüzü olması, en önemli farkı oluşturuyor. Diğer özellikleri (tekrar başlatma gibi) işletim sisteminin desteklediği standart bir mekanizma ile yapmak daha mantıklı geliyor ama web arayüzü de karar verirken etkili bir parametre.
Geribildirim: BigBlueButton ile daha çok kullanıcıya ulaşmak: Scalelite kurulumu - Artistanbul
Geribildirim: ScaleLite Kurulumu – PHP NOTLARIM