Giriş
Paylaşımlı hosting veya ajans ortamlarında tek bir Linux sunucusunda onlarca Django/Flask projesi barındırmak yaygındır. Her proje için ayrı systemd unit yazmak bakım yükünü artırır. uWSGI Emperor modu bu sorunu merkezi bir daemon ile çözer.
Emperor, belirtilen dizindeki .ini dosyalarını izler; yeni dosya eklendiğinde vassal (uşak) process başlatır, silindiğinde sonlandırır. Bu model shared hosting sağlayıcılarının kullandığı klasik mimaridir.
Bu yazıda Emperor kurulumu, vassal ini şablonları, socket izolasyonu ve graceful reload stratejilerini ele alıyoruz.
Emperor Modu Nedir?
Emperor ayrı bir uWSGI instance'ıdır; kendisi HTTP trafiği işlemez, yalnızca vassal'ları yönetir. /etc/uwsgi/emperor.ini ile başlatılır ve emperor = /etc/uwsgi/vassals dizinini izler.
Her vassal kendi ini dosyasındaki module, socket ve process ayarlarıyla bağımsız çalışır. Bir vassal çökerse Emperor yeniden başlatır; diğer siteler etkilenmez.
[uwsgi]
emperor = /etc/uwsgi/vassals
uid = www-data
gid = www-data
master = true
vacuum = true
logto = /var/log/uwsgi/emperor.logVassal Ini Şablonu
Her site için /etc/uwsgi/vassals/siteadi.ini dosyası oluşturulur. virtualenv, chdir ve module zorunludur. Socket yolu site bazında benzersiz olmalıdır.
touch-reload parametresi ile deploy sırasında .ini veya ayrı bir touch dosyasına dokunarak zero-downtime reload yapılır.
- chdir: proje kök dizini
- virtualenv: izole Python ortamı
- socket: nginx uwsgi_pass hedefi
- touch-reload: graceful yeniden yükleme
[uwsgi]
chdir = /var/www/site1
virtualenv = /var/www/site1/venv
module = site1.wsgi:application
socket = /run/uwsgi/site1.sock
chmod-socket = 660
processes = 2
master = true
touch-reload = /var/www/site1/reload.touchSpawn Mekanizması
spawn, Emperor'un vassal başlatma sürecidir. lazy-apps = true her worker'ın uygulamayı ayrı yüklemesini sağlar; C uzantıları ve bazı framework'ler için gereklidir.
cheaper algoritması dinamik worker sayısı ayarlar; düşük trafikte bellek tasarrufu sağlar. Emperor ortamında cheaper dikkatli yapılandırılmalıdır.
[uwsgi]
lazy-apps = true
cheaper = 2
cheaper-initial = 1
cheaper-step = 1
cheaper-algo = spareNginx ile Çoklu Site
Her site için ayrı server bloğu ve uwsgi_pass direktifi tanımlanır. Unix socket kullanımı TCP'ye göre daha hızlı ve güvenlidir.
include uwsgi_params; standart parametre setini yükler. SCRIPT_NAME ve PATH_INFO doğru ayarlanmazsa Django URL routing bozulur.
server {
server_name site1.example.com;
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/site1.sock;
}
}İzleme ve Güvenlik
stats socket ile Emperor ve vassal metrikleri JSON olarak okunabilir. /run/uwsgi/stats.sock üzerinden uwsgi --connect-and-read kullanın.
Her vassal farklı uid/gid ile çalışabilir; müşteri izolasyonu için chroot ve namespace parametreleri değerlendirin. Emperor loglarını merkezi log sistemine yönlendirin.
Emperor ile yönetilen her vassal için ayrı socket, log ve touch-reload dosyası kullanın; çakışma üretimde felakete yol açar.
Deploy ve Reload
Kod deploy'unda touch reload.touch yeterlidir; Emperor vassal'ı graceful yeniden yükler. ini değişikliklerinde dosya otomatik algılanır.
systemd ile uwsgi-emperor.service tek unit yeterlidir; onlarca site için ayrı service gerekmez.
[Unit]
Description=uWSGI Emperor
After=network.target
[Service]
ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/emperor.ini
Restart=alwaysSonuç
Emperor modu çok siteli Python hosting için kanıtlanmış bir çözümdür. Doğru ini şablonları, socket izolasyonu ve touch-reload ile operasyonel yük dramatik azalır.
Küçük tek proje için Emperor gereksiz karmaşıklık olabilir; 5+ uygulama barındırıyorsanız mutlaka değerlendirin.