İçeriğe geç
Muhammet Şafak
en
Güncelleme 1 dk okuma

Nginx + PHP-FPM Pool Ayrımı

Aynı VPS üzerinde birden fazla PHP uygulaması çalıştırırken, tek bir PHP-FPM pool yerine uygulama başına ayrı pool tanımlamanın somut faydaları.

Kısaca

Uygulama başına ayrı bir PHP-FPM pool'u iki şeyi ayırır: dosya sistemi erişimini ve worker bütçesini. Ayırmadığı şey opcache ve reload — pool'lar tek bir master'ı paylaşır ve o master'ın tek yeniden yükleme sinyali bütün worker'ları birlikte götürür. İzolasyon çalışma zamanında geçerli, deploy yolunda değil. Hangisini satın aldığınızı bilerek kurun.

Nginx + PHP-FPM Pool Ayrımı — kapak görseli

VPS üzerinde iki, üç, beş PHP uygulaması çalıştırmak — küçük SaaS dünyasında çok normal. Default kurulumda hepsi tek bir www.conf pool’unu paylaşıyor. Bu çoğu zaman çalışıyor — çalışmayana kadar.

Tek pool’da ne ters gider?

Tek pool şu anlama geliyor:

  1. Bir uygulama pm.max_children = 50’yi tüketirse diğerleri response üretemez.
  2. Bir uygulamadaki memory leak diğerlerinin worker’larını da OOM’a sürükler.
  3. Bir uygulamayı yeniden başlatmak (örn. opcache reset) hepsinin worker’larını yeniden başlatır.

Pool ayrımı ilk iki sorunu çözüyor. Üçüncüsünü çözmüyor: PHP-FPM’de pool başına reload yok — tek yeniden yükleme sinyali SIGUSR2, master altındaki tüm worker’ları yeniden yüklüyor.

Pool başına config

/etc/php/8.4/fpm/pool.d/billing.conf:

[billing]
user = billing
group = billing
listen = /run/php/billing.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500

request_terminate_timeout = 30s
catch_workers_output = yes
decorate_workers_output = no
clear_env = no

php_admin_value[memory_limit] = 256M
php_admin_value[error_log] = /var/log/php-fpm/billing-error.log

/etc/php/8.4/fpm/pool.d/notify.conf:

[notify]
user = notify
group = notify
listen = /run/php/notify.sock
; ...
pm.max_children = 8       ; daha hafif uygulama
php_admin_value[memory_limit] = 128M

İki şey kazandık:

  • Filesystem izolasyonu — user = billing ile billing uygulaması notify’ın dosyalarına yazamaz.
  • Resource izolasyonu — billing’in pm.max_children’i tükenirse notify hâlâ çalışır.

Nginx tarafında

Her vhost kendi socket’ine bağlanıyor:

server {
    server_name billing.example.com;
    root /var/www/billing/public;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/billing.sock;
        # standart fastcgi params
    }
}

server {
    server_name notify.example.com;
    root /var/www/notify/public;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/notify.sock;
    }
}

opcache shared mı, ayrı mı?

PHP-FPM master process’i opcache’i paylaşıyor — bu yüzden pool’lar arasında opcache otomatik izole değildir. opcache.validate_root = 1 bunu değiştirmiyor: bu direktif chroot’lu ortamlardaki ad çakışmalarını önlemek için / dizininin inode’unu önbellek anahtarına katıyor, yani ayırt ettiği şey chroot kökleri, metindeki Nginx root path’leri değil — ve buradaki pool’larda chroot yok. Pratikte: aynı master, ayrı pool’lar yeterli.

İzleme

/status endpoint’ini pool’a açın:

pm.status_path = /status

Sonra Nginx tarafında bunu sadece localhost’a açın:

location ~ ^/status$ {
    access_log off;
    allow 127.0.0.1;
    deny all;
    fastcgi_pass unix:/run/php/billing.sock;
    # ...
}

curl localhost/status ile aktif worker, kuyruk uzunluğu, slow request sayısı gibi metrikleri alıp Prometheus exporter veya basit bir cron’la izleyebilirsiniz.

Ne zaman tek pool yeterli?

Aynı kod tabanının iki kopyasını çalıştırıyorsanız (örn. app.example.com ve staging.example.com) ayrı pool gereksiz. Farklı domain’ler ama aynı süreç sınıfı. Ayrım, uygulamaları operasyonel olarak bağımsız kılmak istediğinizde değerli.

Sık sorulanlar

3 soru

  • Pool ayrımı uygulamalar arasında opcache'i izole eder mi?

    Hayır. Pool'lar tek bir PHP-FPM master'ı altında çalışır ve onun opcache'ini paylaşır. opcache.validate_root da bunu değiştirmez: o direktif chroot'lu ortamlardaki ad çakışmalarını önlemek için vardır ve buradaki pool'larda chroot yoktur. Ayrı pool, dosya sistemi ve kaynak izolasyonu getirir; ayrı bir opcode cache değil.

  • Tek bir PHP-FPM pool tek başına reload edilebilir mi?

    Hayır. FPM'de tek bir yeniden yükleme sinyali var, SIGUSR2, ve o da tüm worker'ları graceful biçimde yeniden yükleyip FPM yapılandırmasını baştan okuyor. Pool başına bir sinyal yok; bu yüzden bir uygulamayı yeniden başlatmak makinedeki diğer bütün pool'ları da geri döndürüyor.

  • Ne zaman tek pool yeterli olur?

    Uygulamalar aynı süreç sınıfındaysa — aynı kod tabanının iki kopyası, örneğin farklı domain'lerde production ve staging. Ayrım, uygulamaların birbirinden operasyonel olarak bağımsız olmasını istediğinizde değerli.

Kaynaklar

İlgili

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi