Merhaba arkadaşlar, bugün sizlere özellikle yüksek trafikli sunucularda hayati önem taşıyan, PHP-FPM process manager ayarlarından `pm.max_children` ve `pm.start_servers` değerlerini nasıl doğru ve güvenli bir şekilde hesaplayacağımızı anlatacağım. Bu ayarları doğru yapmak, sunucunuzun bellek tükenmesi (OOM) hatası vermeden, maksimum performansta çalışmasını sağlar. Yanlış ayarlar ise sitenizin yavaşlamasına, hatta tamamen çökmesine neden olabilir.
Öncelikle Mevcut Durumu Anlayalım
İşe, sunucumuzda ne kadar kaynak olduğunu ve mevcut PHP süreçlerinin ne kadar bellek tükettiğini ölçerek başlamalıyız. Bu adımı atlarsak, tüm hesaplarımız havada kalır.
Öncelikle, sunucunuzdaki toplam kullanılabilir belleği kontrol edelim. Ben genelde `free -m` komutunu kullanırım.
Çıktıdaki `Mem` satırındaki `total` değeri toplam belleğinizi MB cinsinden gösterir. Ancak, sunucuda sadece PHP değil, Nginx/Apache, MySQL, ve diğer servisler de çalıştığı için PHP'ye ayırabileceğimiz güvenli bir bellek limiti belirlemeliyiz.
Şimdi de mevcut bir PHP-FPM sürecinin ortalama ne kadar RAM tükettiğini ölçelim. Bunun için `ps` komutunu kullanabiliriz.
Bu komut, çalışan tüm PHP-FPM süreçlerinin ortalama bellek tüketimini (RSS) MB cinsinden verecektir. Bu değer, sitenizdeki ortalama bir sayfa yükünü temsil eder. Daha doğru bir ölçüm için siteniz normal trafikteyken bu komutu birkaç kez çalıştırmanızı tavsiye ederim.
pm.max_children Değerini Hesaplama
`pm.max_children`, aynı anda çalışabilecek maksimum PHP süreç sayısıdır. Bu değeri hesaplarken şu formülü kullanıyoruz:
`pm.max_children = (Sunucuya Ayırabileceğimiz Güvenli Bellek) / (Bir PHP Sürecinin Ortalama Bellek Tüketimi)`
Örnek bir hesaplama yapalım:
- Sunucunuzda 8GB (8192MB) RAM olduğunu varsayalım.
- Diğer servisler (Nginx, MySQL, sistem) için 3GB (3072MB) ayırdığımızı düşünelim. Bu, sunucu yükünüze göre değişir, benim sunucularımda genelde kullandığım bir orandır.
- PHP'ye ayırabileceğimiz güvenli bellek: 8192MB - 3072MB = 5120MB.
- Bir PHP sürecinin ortalama tüketimi de ölçtüğümüzde 150MB çıktığını varsayalım.
Hesaplama: 5120MB / 150MB ≈ 34.13
Bu durumda, `pm.max_children` değerini güvenli tarafta kalmak için 34 olarak ayarlayabiliriz. Bu değeri asla tam bellek kapasitesine göre hesaplamayın, mutlaka bir tampon (buffer) bırakın. Aksi takdirde, ani bir trafik patlamasında tüm beliğiniz tükenir ve sunucu çöker.
pm.start_servers ve Diğer Dinamik Ayarlar
`pm.start_servers`, FPM başladığında otomatik olarak oluşturulacak süreç sayısıdır. Dinamik (`pm = dynamic`) modda çalışıyorsanız, bu ve diğer iki ayar çok önemlidir. Genel kabul görmüş formül şudur:
`pm.start_servers = (Ortalama eşzamanlı kullanıcı sayısına göre tahmin)`
Daha pratik bir yaklaşım: `pm.max_children 0.25` gibi bir oranla başlayıp, sunucu monitorizasyon araçlarınızla (NetData, Grafana) izleyerek optimize edebilirsiniz.
Benim genel tavsiyem şu şekilde olur:
`pm.max_requests` ayarı, belirli sayıda istek işleyen bir sürecin öldürülüp yeniden başlatılmasını sağlar. Bu, uzun süreli çalışan süreçlerde oluşabilecek hafıza sızıntılarını (memory leaks) temizlemek için çok faydalıdır. 500-1000 arası bir değer genelde iyi sonuç verir.
Dikkat Edilmesi Gerekenler ve Test
Bu ayarları yaptıktan sonra asla "oldumu" deyip bırakmayın. Mutlaka test edin!
1. Ayarları Uygulama: PHP-FPM pool konfigürasyon dosyanız (genelde /etc/php/7.x/fpm/pool.d/www.conf veya benzeri bir yol) içindeki bu değerleri düzenleyin.
2. Servisi Yeniden Başlatın:
(Sürümünüze göre)
3. Yük Testi Yapın: `ab` (Apache Benchmark) veya `siege` gibi araçlarla sunucunuza biraz yük bindirip, bellek ve süreç durumunu izleyin.
komutu ile anlık süreç sayısını takip edebilirsiniz.
4. Monitorizasyon: Uzun vadede, gerçek trafik altında sunucu bellek ve yük durumunuzu izleyin. Eğer swap kullanımı sürekli artıyorsa veya bellek tükenme uyarıları alıyorsanız, `pm.max_children` değerinizi düşürmeniz gerekebilir.
Sonuç ve Öneriler
Unutmayın arkadaşlar, sihirli bir formül yok. Her sunucunun yükü, kullandığı eklentiler ve kod yapısı farklıdır. Bu rehber, size sağlam ve güvenli bir başlangıç noktası verecektir. En iyi ayarı, kendi trafiğinizi ve sunucu metriklerinizi sürekli izleyerek siz bulacaksınız.
Peki siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? Farklı bir hesaplama yönteminiz veya tavsiyeleriniz var mı? Takıldığınız bir nokta olursa aşağıya yazmaktan çekinmeyin, beraber çözelim.
İşe, sunucumuzda ne kadar kaynak olduğunu ve mevcut PHP süreçlerinin ne kadar bellek tükettiğini ölçerek başlamalıyız. Bu adımı atlarsak, tüm hesaplarımız havada kalır.
Öncelikle, sunucunuzdaki toplam kullanılabilir belleği kontrol edelim. Ben genelde `free -m` komutunu kullanırım.
Bash:
free -m
Çıktıdaki `Mem` satırındaki `total` değeri toplam belleğinizi MB cinsinden gösterir. Ancak, sunucuda sadece PHP değil, Nginx/Apache, MySQL, ve diğer servisler de çalıştığı için PHP'ye ayırabileceğimiz güvenli bir bellek limiti belirlemeliyiz.
Şimdi de mevcut bir PHP-FPM sürecinin ortalama ne kadar RAM tükettiğini ölçelim. Bunun için `ps` komutunu kullanabiliriz.
Bash:
ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024, "MB") }'
Bu komut, çalışan tüm PHP-FPM süreçlerinin ortalama bellek tüketimini (RSS) MB cinsinden verecektir. Bu değer, sitenizdeki ortalama bir sayfa yükünü temsil eder. Daha doğru bir ölçüm için siteniz normal trafikteyken bu komutu birkaç kez çalıştırmanızı tavsiye ederim.
`pm.max_children`, aynı anda çalışabilecek maksimum PHP süreç sayısıdır. Bu değeri hesaplarken şu formülü kullanıyoruz:
`pm.max_children = (Sunucuya Ayırabileceğimiz Güvenli Bellek) / (Bir PHP Sürecinin Ortalama Bellek Tüketimi)`
Örnek bir hesaplama yapalım:
- Sunucunuzda 8GB (8192MB) RAM olduğunu varsayalım.
- Diğer servisler (Nginx, MySQL, sistem) için 3GB (3072MB) ayırdığımızı düşünelim. Bu, sunucu yükünüze göre değişir, benim sunucularımda genelde kullandığım bir orandır.
- PHP'ye ayırabileceğimiz güvenli bellek: 8192MB - 3072MB = 5120MB.
- Bir PHP sürecinin ortalama tüketimi de ölçtüğümüzde 150MB çıktığını varsayalım.
Hesaplama: 5120MB / 150MB ≈ 34.13
Bu durumda, `pm.max_children` değerini güvenli tarafta kalmak için 34 olarak ayarlayabiliriz. Bu değeri asla tam bellek kapasitesine göre hesaplamayın, mutlaka bir tampon (buffer) bırakın. Aksi takdirde, ani bir trafik patlamasında tüm beliğiniz tükenir ve sunucu çöker.
`pm.start_servers`, FPM başladığında otomatik olarak oluşturulacak süreç sayısıdır. Dinamik (`pm = dynamic`) modda çalışıyorsanız, bu ve diğer iki ayar çok önemlidir. Genel kabul görmüş formül şudur:
`pm.start_servers = (Ortalama eşzamanlı kullanıcı sayısına göre tahmin)`
Daha pratik bir yaklaşım: `pm.max_children 0.25` gibi bir oranla başlayıp, sunucu monitorizasyon araçlarınızla (NetData, Grafana) izleyerek optimize edebilirsiniz.
Benim genel tavsiyem şu şekilde olur:
NGINX:
pm = dynamic
pm.max_children = 34
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 12
pm.max_requests = 500
`pm.max_requests` ayarı, belirli sayıda istek işleyen bir sürecin öldürülüp yeniden başlatılmasını sağlar. Bu, uzun süreli çalışan süreçlerde oluşabilecek hafıza sızıntılarını (memory leaks) temizlemek için çok faydalıdır. 500-1000 arası bir değer genelde iyi sonuç verir.
Bu ayarları yaptıktan sonra asla "oldumu" deyip bırakmayın. Mutlaka test edin!
1. Ayarları Uygulama: PHP-FPM pool konfigürasyon dosyanız (genelde /etc/php/7.x/fpm/pool.d/www.conf veya benzeri bir yol) içindeki bu değerleri düzenleyin.
2. Servisi Yeniden Başlatın:
Bash:
sudo systemctl restart php7.x-fpm
3. Yük Testi Yapın: `ab` (Apache Benchmark) veya `siege` gibi araçlarla sunucunuza biraz yük bindirip, bellek ve süreç durumunu izleyin.
Bash:
watch -n 1 "ps aux | grep php-fpm | wc -l"
4. Monitorizasyon: Uzun vadede, gerçek trafik altında sunucu bellek ve yük durumunuzu izleyin. Eğer swap kullanımı sürekli artıyorsa veya bellek tükenme uyarıları alıyorsanız, `pm.max_children` değerinizi düşürmeniz gerekebilir.
Unutmayın arkadaşlar, sihirli bir formül yok. Her sunucunun yükü, kullandığı eklentiler ve kod yapısı farklıdır. Bu rehber, size sağlam ve güvenli bir başlangıç noktası verecektir. En iyi ayarı, kendi trafiğinizi ve sunucu metriklerinizi sürekli izleyerek siz bulacaksınız.
Peki siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? Farklı bir hesaplama yönteminiz veya tavsiyeleriniz var mı? Takıldığınız bir nokta olursa aşağıya yazmaktan çekinmeyin, beraber çözelim.