Laravel Üretim Performansını Birlikte Değerlendirmek
Trafik artışında görülen 502 hatası veya yüksek yanıt süresi tek bir ayarın bozuk olduğunu kanıtlamaz. PHP çalışanlarının dolması, veritabanı kilitleri, dış servisler ve bellek baskısı benzer belirtiler oluşturabilir. Önce yavaşlayan işlemi, hata anını ve kaynak kullanımını birlikte kaydedin; ardından ölçümün işaret ettiği bileşeni değiştirin.
Bu Laravel üretim optimizasyonu rehberi PHP-FPM, OPcache, Octane, Horizon ve Redis arasındaki ilişkileri açıklar. Teknik kapsam Laravel 12, Horizon 5.x ve Octane 2.x’tir; PHP 8.2 bu Laravel sürümünün desteklediği tabandır. Kurulu paketlerin kilit dosyasını, eklentileri ve işletim sisteminin hizmet adlarını ayrıca kontrol edin. Octane, HTTP istekleri için alternatif bir uzun ömürlü çalışma modelidir; FPM çalışanlarının üzerine eklenen bir hızlandırıcı değildir.
PHP-FPM Havuzlarını Kaynak Bütçesine Göre Ayarlayın
pm.max_children, havuzun aynı anda işleyebileceği istek sayısını sınırlar. Az çalışan kuyruk beklemesini artırabilir; fazla çalışan ise RAM, CPU ve veritabanı bağlantılarını tüketebilir. Ayrı havuzlar farklı yollar için çalışan kapasitesi ayırır, fakat ortak CPU, RAM veya veritabanını izole etmez. Bu kaynaklar için toplam bütçe ve gerekirse işletim sistemi seviyesinde sınırlar gerekir.
İşlem başına sabit bir MB değeri varsaymayın. Temsili yoğun isteklerde özel bellek kullanımını ve süreç grubunun orantılı belleğini (PSS) ölçün; kısa süreli ortalama ağır uçları gizleyebilir. RSS değerlerini çalışan sayısıyla çarpmak paylaşılan OPcache sayfalarını birden fazla sayabilir. İşletim sistemi, veritabanı, Redis, OPcache ve arka plan işleri için pay ayırdıktan sonra FPM’in tepe ihtiyacını hesaplayın. CPU ve downstream bağlantı sınırları bu bellek hesabından daha düşük eşzamanlılık gerektirebilir. dynamic modunda start/min/max spare ayarları geçerlidir; ondemand boşta süreçleri azaltır fakat ani yükte süreç başlatma gecikmesi ekleyebilir. static sabit sayıda çalışan tutar. Her değişiklikten sonra kuyruk, p95/p99 süre ve swap’i birlikte izleyin.
İlk Temas: Zaman Aşımı ve Kuyruk Etkisi
Uygulamanın dış servis bağlantı ve okuma zaman aşımlarını, FPM ve web sunucusu sınırlarını birlikte tasarlayın. request_terminate_timeout süre dolunca çalışanı sonlandırır; işi otomatik olarak kuyruğa taşımaz ve başlamış yan etkileri geri almaz. Uzun raporları uygulama kodunda açıkça kuyruğa gönderin. Kullanıcıya iş kimliği ve durum/sonuç erişimi sağlayın; web isteğinin işi sıraya koyabildiğini doğrulayın.
Loglar, yavaşlar ve görünürlük
request_slowlog_timeout eşiğini aşan istekler için slowlog PHP çağrı izini kaydeder; log dizininin mevcut ve FPM master süreci tarafından yazılabilir olması gerekir. pm.status_path havuz ve istek bilgileri açığa çıkarır: yalnızca özel bir yönetim dinleyicisinden eriştirin, bütün genel vhost’larda bu yolu engelleyin. Reverse proxy arkasında yalnızca istemci IP’si allowlist’ine güvenmeyin. Slowlog ve havuz kuyruğu teşhis ipuçlarıdır; N+1 sorgusunu veya yavaş dış çağrıyı uygulama izleri ve sorgu kayıtlarıyla doğrulayın.
OPcache Belleği ve Dağıtımda Kod Yenileme
OPcache, derlenmiş PHP bytecode’unu bellekte tutarak tekrar derleme ihtiyacını azaltır. Bellek tüketimini, önbelleğe alınan script sayısını, doluluk ve yeniden başlatma sayaçlarını erişimi kısıtlı araçlarla inceleyin. opcache.memory_consumption, opcache.interned_strings_buffer ve script kapasitesini uygulamanın gerçek ihtiyacına göre ayarlayın; boş alanı görmeden büyütmeyin. Resmî OPcache yapılandırma belgesi seçeneklerin kapsamını açıklar. PHP 7.2’de kaldırılmış opcache.fast_shutdown PHP 8.2 örneklerinde kullanılmamalıdır.
opcache.validate_timestamps=0 yalnızca her dağıtımda ilgili çalışma ortamının kod önbelleğini güvenilir biçimde yenileyebiliyorsanız uygundur. Aksi halde eski kod sunulabilir; zaman damgası denetimini açık tutun. CLI’den opcache_reset() çalıştırmak FPM’in önbelleğini temizlemez. FPM için kurulu hizmetin kontrollü reload/restart davranışını test edin; Octane ve kuyruk çalışanlarını ayrıca yenileyin. JIT’i otomatik kazanç saymayın: aynı yükte ölçün, özellikle veritabanı veya ağ beklemesinin baskın olduğu isteklerde PHP hesaplama hızının toplam süreye etkisi sınırlı kalabilir.
Deploy Anlarında OPcache’i Ürkütmeden Yenilemek
Yeni sürümü ayrı bir dizinde hazırlayın, hedef üretim ortamı değişkenleriyle Laravel cache dosyalarını oluşturun ve kontroller geçmeden trafiği taşımayın. Geçişte ilgili FPM neslini doğrulanmış yöntemle yenileyin; ardından yeni süreçlere sağlık ve ısınma istekleri gönderin. Isıtıp sonra önbelleği sıfırlamak kazanımı yok eder. Symlink değişimi tek başına sıfır kesinti veya eski süreçlerin yeni koda geçtiği anlamına gelmez. Eski sürümü çalışan istekler bitene kadar saklayın, geri dönüşü veritabanı şemasıyla birlikte planlayın. opcache.file_cache kullanılıyorsa disk önbelleği ve sürüm yolları da bu plana dahil olmalıdır.
Octane Ne Zaman Faydalı Olur?
Octane Laravel uygulamasını bir kez başlatıp aynı worker içinde sonraki isteklerde yeniden kullanır. Framework başlatma süresi önemliyse yarar sağlayabilir; uzak servis veya veritabanı beklemesini ortadan kaldırmaz. Statik alanlar ve singleton içinde tutulan kullanıcı/istek verisi sonraki isteğe sızabilir. Framework’ün kendi durum temizliği uygulamanın her global değişkenini kapsamaz. Octane belgelerindeki bağımlılık enjeksiyonu kurallarını uygulayın; kullanıcı bağlamını scoped bağlamalarda veya açık istek parametrelerinde tutun ve farklı kullanıcı isteklerini aynı worker’a art arda göndererek sınayın.
Octane 2.x, uygun gereksinimlerle FrankenPHP, RoadRunner veya Swoole kullanabilir. Worker sayısını kullanılabilir CPU, tepe bellek ve aynı hosttaki kuyruk yüküne göre belirleyin; çekirdek başına bir worker bile evrensel güvenli ayar değildir. --workers, Swoole için --task-workers ve --max-requests desteklenen başlangıç seçenekleridir. İstek sayısı sonunda worker yenilemek bellek büyümesini sınırlayabilir ama veri sızıntısını düzeltmez. Geliştirme için --watch ayrı bir CLI seçeneğidir; production’da süreç gözetimi ve kontrollü yeniden yükleme kullanın.
Octane ile Queue ve Cache’in Dili Aynı Olmalı
Kalıcı, yeniden denenecek işleri Laravel kuyruklarına gönderin. Swoole task worker’larını Horizon tarafından izlenen dayanıklı işler gibi değerlendirmeyin. Cache anahtarları için uygulamaya özgü ad alanı, uygun TTL ve geçersizleştirme stratejisi belirleyin. Redis kalıcı bağlantıları her kurulumda otomatik hız kazandırmaz; bağlantı sayısı, zaman aşımı ve uzun yaşayan süreçlerde eski bağlantı davranışı ölçülmelidir. Kullanıcıya bağlı veriyi global bir bellek önbelleğinde paylaşmayın.
Horizon Kuyrukları, Zaman Aşımı ve Tekrarlar
Varsayımsal bir rapor akışında web isteği rapor işini kuyruğa bırakır ve iş kimliğini döndürür; worker dosyayı üretince uygulama kullanıcıya hazır olduğunu gösterir. Kuyruğa taşıma toplam hesaplama işini azaltmaz, beklemeyi web yanıtından ayırır. Horizon Redis kuyrukları gerektirir; kuyruk yaşı, iş süreleri ve başarısızlıkları izlemeye yardımcı olur. Dashboard’daki viewHorizon yetkilendirme kapısını üretimde yetkili kullanıcılarla sınayın.
Horizon supervisor’ları, işletim sistemindeki Supervisor süreç gözetmeniyle aynı katman değildir. Horizon 5.x’te defaults seçenekleri supervisor adına göre gruplanır. auto iş yüküne göre çalışan dağılımını değiştirir; simple sabit süreçleri kuyruklar arasında eşit dağıtır; false kuyrukları belirtilen sırayla işler. minProcesses, maxProcesses, balanceMaxShift ve balanceCooldown ayarlarını seçilen modla tutarlı kullanın. Ağır işleri ayrı supervisor ile sınırlayın; tüm supervisor’ların azami çalışanlarını host bütçesinde toplayın.
Timeout, Retry ve Başarısız İşler
İş düzeyindeki $timeout, Horizon timeout değerinden küçük; Horizon timeout da Redis kuyruk bağlantısının retry_after değerinden birkaç saniyeden fazla payla küçük olmalıdır. Örneğin 300 saniye Horizon sınırı için 360 saniye retry_after düşünülebilir; bütün işler ve bağlantılar bu ilişkiye uymalıdır. PHP PCNTL eklentisi ile dış çağrıların bağlantı/okuma zaman aşımlarını doğrulayın. tries toplam deneme sayısını, backoff hata sonrası beklemeyi, maxTime worker ömrünü belirler; bunlar aynı sınır değildir. Worker bellek eşiği tepe tüketimine karşı sert bir host kotası değildir. Kesinti ve yeniden deneme aynı işi tekrar çalıştırabilir: ödeme gibi yan etkileri idempotency anahtarı veya benzersiz işlem kaydıyla koruyun, failed jobs kayıtlarını incelemeden topluca tekrar göndermeyin.
Redis: Kuyrukları Silinebilir Cache’ten Ayırın
allkeys-lru yalnızca yeniden üretilebilen cache verisi için düşünülebilir; kuyruk veya kilit anahtarlarına uygulanırsa doğruluk bozulabilir. Ayrı mantıksal Redis DB numaraları aynı instance’ın bellek, eviction ve kalıcılık kurallarını paylaşır. Kuyruk/korunması gereken veriyi ayrı bir instance’a taşıyın; burada noeviction anahtar tahliyesini engeller ama bellek dolduğunda yeni veri oluşturan komutlar hata verir. Dispatch hatalarını izleyin ve kapasite payı bırakın. Redis yapılandırma rehberi temel seçenekleri açıklar; instance ayrımı tek başına yüksek erişilebilirlik değildir.
PhpRedis PHP ile yerleşik gelen bir bileşen değil, ayrıca kurulup ilgili PHP çalışma ortamında etkinleştirilen bir eklentidir. CLI worker ve FPM farklı ini dosyaları kullanabilir. UNIX socket aynı hostta erişim ve izin yönetimi sağlayabilir; otomatik performans garantisi değildir. Redis başka sunucuya taşınırsa ağ gecikmesi, kimlik doğrulama, gerektiğinde TLS ve bağlantı kesintisi davranışı da plana eklenir. Redis, PHP ve veritabanının toplam RAM/CPU bütçesini birlikte hesaplayın.
Key Adlandırma, TTL ve İzleme
app:cache:user:123 gibi ad alanları uygulama anahtarlarını ayırır; anahtar adları tek başına erişim güvenliği sağlamaz. TTL’leri verinin yenilenme ihtiyacına göre seçin ve eşzamanlı cache miss dalgasını kontrol edin. Laravel’in kuyruk iç anahtarlarına gelişigüzel TTL koymayın. maxmemory toplam RSS sınırı değildir; işletim sistemi, bağlantı tamponları ve kalıcılık sırasında fork/bellek payını koruyun. AOF everysec son yazıların yaklaşık bir saniyelik bölümünün kaybını göze alan bir dayanıklılık tercihidir; kilit doğruluğu veya sıfır veri kaybı garantisi değildir. Redis’in THP önerisi Linux Transparent Huge Pages içindir, tüm huge page türlerini aynı saymayın. Gecikme, bellek, eviction, reddedilen yazmalar ve kalıcılık hatalarını birlikte izleyin.
Dağıtım ve İzleme Adımlarını Sıralayın
Yeni sürüm dizininde composer install --no-dev --optimize-autoloader bağımlılıkları kilit dosyasına göre kurar ve autoloader’ı optimize eder; bunlar OPcache bayrakları değildir. config:cache, route:cache ve view:cache hedef ortam için oluşturulmalıdır. Laravel 12’de optimize bu cache’leri ve event cache’ini bir arada hazırlayabilir. Config cache sonrasında .env normal şekilde yüklenmez; env() çağrılarını config dosyalarında tutun ve uygulamada config() kullanın. Şema değişimini eski/yeni kod ve bekleyen işler açısından uyumlu planlayın; geçiş, süreç yenileme ve sağlık kontrolü başarısızsa geri dönüş adımları hazır olmalıdır.
Timeout artırmak kapasite sorununu ortadan kaldırmaz. HTTP hata oranı ve p95/p99 süreleri, FPM listen queue/max children sayaçları, veritabanı sorgu/lock süreleri, Redis hataları ve kuyruk yaşı aynı zaman çizelgesinde görünmelidir. Log rotasyonu ve disk doluluk alarmları da gereklidir. Prometheus ve Grafana ile VPS izleme rehberi bu sinyaller için başlangıç noktasıdır; alarm eşiklerini uygulamanın hedeflerine göre belirleyin.
Örnek Akış: Yoğun Trafikte Darboğazı Bulmak
Ölçülecek bir senaryo olarak sabah trafiğinde geciken raporları düşünün. Önce FPM kuyruğunu, raporun sorgularını ve harici çağrılarını izleyin. İş kuyruğa taşınacaksa kullanıcıya bekleyen/başarılı/başarısız durumları sunun. Worker sayısını özel tepe bellek ve downstream sınırlarıyla belirleyin. OPcache doluluğu kanıtlanmışsa bütçeyi düzeltin; zaman damgasını kapatma kararını yalnızca test edilmiş dağıtım prosedürü varsa alın.
Bu senaryoda Octane’i ancak bootstrap maliyeti önemli kaldıysa deneyin. Aynı worker’a farklı kullanıcıların ardışık isteklerini göndererek durum ayrımını sınayın; bellek ve veritabanı bağlantılarının zaman içindeki davranışını ölçün. Horizon ölçeklemesinin toplam host bütçesini aşmadığını ve Redis kuyruk anahtarlarının silinebilir cache politikasına maruz kalmadığını doğrulayın. Bu akış bir müşteri sonucu veya belirli hız kazancı iddiası değildir; başarı ölçütü doğru sonuç, kabul edilebilir gecikme ve hata oranıdır.
Laravel ve Node.js için VPS kaynaklarını seçme rehberi kapasite planlamasını tamamlar. Önce uygulamanın gerçek tepe yükünü ve hizmet limitlerini belirleyin. Yeni kaynak eklemek hatalı sorguyu, yanlış timeout ilişkisini veya istekler arası veri sızıntısını düzeltmez.
Değişiklikleri Ölçümle Doğrulayın
Her değişiklik için önceki ve sonraki veri kümesini, trafik oranını ve cache durumunu kaydedin. PHP-FPM kapasitesi, OPcache yenilenmesi, Horizon tekrarları, Redis kalıcılığı ve Octane kullanıcı ayrımı farklı doğrulamalar ister. Yalnızca ortalama yanıt süresine bakmayın; p95/p99, hatalar, kuyrukta en uzun bekleme ve iş sonuçlarının doğruluğu birlikte değerlendirilmelidir.
Önce gözlem yapın, sonra tek bir gerekçeli değişikliği test edin. Aşırı eşzamanlılığı azaltın, uzun işleri idempotent kuyruk tasarımına taşıyın ve silinebilir cache ile korunacak veriyi ayırın. Kaynak bütçesini ve dağıtım geri dönüş planını güncel tutun. Bu yaklaşım arıza olasılığını azaltmaya yardımcı olur; herhangi bir ayar 502 hatalarının tamamen biteceğini garanti etmez.
Dağıtımda Hangi Süreç Yenilenir?
Yeni sürümde php artisan config:cache, php artisan route:cache ve php artisan view:cache hazırlayın. Normal queue:work süreçlerine php artisan queue:restart, Horizon’a php artisan horizon:terminate, çalışan Octane worker’larına php artisan octane:reload uygulanır. Queue restart sinyalinin kullandığı cache erişilebilir olmalı; Horizon ve normal worker’lar süreç gözetmeniyle yeni sürümden yeniden başlamalıdır. Gözetmenin stopwaitsecs değeri en uzun işten ve kapanış payından büyük olmalıdır. FPM için örneğin Debian PHP 8.2 kurulumunda sudo systemctl reload php8.2-fpm ancak o birim ve cache yenileme davranışı doğrulanmışsa kullanılabilir. Komutlar birbirinin yerine geçmez; uygulamada kullanılan süreçlere göre seçilir. Horizon pause yeni iş alımını durdurur, bekleyen eski payload’ları tüketmez: uyumsuz değişiklikte üreticileri durdurun, eski uyumlu worker’ların bekleyen işleri tamamlamasını sağlayın ve sonra sürüm değiştirin; alternatif olarak sürümler arası payload/şema uyumunu koruyun.
Kaynak Notları
Temel referanslar: OPcache yapılandırması, Laravel Octane belgeleri ve Redis konfigürasyonu. Bu yazının sürüm kapsamı için ayrıca Laravel 12 Horizon, kuyruk ve dağıtım belgelerini kullanın. Paket veya PHP sürümü değiştiğinde örnekleri tekrar doğrulayın.





