DeployerPHP zero-downtime deploy'da OPcache'ten gelen 500 hatalarını nasıl engellerim?
Soru
DeployerPHP ile deploy ediyoruz: `releases/X` oluşuyor, `composer install` çalışıyor, asset'ler derleniyor, en son `current` symlink yeni klasöre dönüyor. Bu symlink değişiminde PHP-FPM'in OPcache'inde eski kodlar kaldığı için (cache poisoning) 500 hataları çıkıyor. Pipeline'a `php-fpm reload` ve OPcache temizliğini güvenli şekilde nasıl entegre ederim?
Cevap
Kısa cevap: Symlink çevirmek atomik ama yeterli değil — flip’ten sonra PHP-FPM’i graceful reload etmen lazım; OPcache’i hiçbir release’den sonra eski koda yapışık bırakma.
Yaşadığın şey klasik OPcache cache poisoning: OPcache, derlenmiş bytecode’u dosya yoluna göre keyler. current symlink’inin kendi yolu hiç değişmediği için worker’lar bir önceki release’in bytecode’unu sunmaya devam eder; bazı worker’lar eski, bazıları yeni realpath’i görünce dosya yolları karışır ve 500 patlar.
- En temiz yol: symlink’ten sonra PHP-FPM’i graceful reload et.
kill -USR2 <fpm-master>ya dasystemctl reload php-fpm— bu, FPM’in yenirealpath’i görmesini sağlar ve OPcache’i tazeler. Reload, restart değil: mevcut istekler tamamlanır, yeni worker’lar yeni kodu derler, kesinti olmaz. Deployer’da bunudeploy:symlinkadımına hook’la. - Alternatif:
opcache_reset()’i deploy hook’undan çağır. FPM soketinecachetoolile bağlanıp cache’i resetlemek, web’den bir reset endpoint’i tetiklemekten daha temiz — CLI ve FPM ayrı OPcache tutar, yaniphp artisanile resetlemek FPM’i etkilemez. Reload bunu zaten kapsadığı için çoğu zaman gerek kalmaz. opcache.revalidate_freq’i ayarlamak tek başına çözüm değil. Aynı dosya yolu değiştiğinde işe yarar; ama release’ler arası yol farkında revalidate seni kurtarmaz. Release sınırında garantili olan reset/reload’dur.- Octane bambaşka bir hikaye. Octane’de kod diskten değil bellekten sunulur; uzun ömürlü worker’lar eski sınıfları RAM’de tutar. Symlink flip’ten sonra
php artisan octane:reloadile worker’ları yenilemen şart, yoksa OPcache’i ne yaparsan yap eski kod ayakta kalır.
Sonuç: Akış net olsun — symlink’i çevir → PHP-FPM’i graceful reload et (Octane’deysen octane:reload) → istersen opcache_reset. Bunu Deployer’da symlink adımına bağla ve bir release’den sonra OPcache’i asla eski koda yapışık bırakma. Octane’in bellekte kod tutmasının deploy tarafındaki bedeli ayrı bir hub yazısının konusu; oradaki kalıcı-süreç modelini iyi tanırsan bu reload adımını atlamazsın.
İlgili Yazılar
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.