Swoole, RoadRunner ve OPcache Preloading Karşılaştırması
Klasik PHP çalışma modeli
İstek Geldi
Laravel Bootstrap
~80ms
Cevap Dön
Problem: Her istekte Laravel tamamen yeniden başlatılıyor:
Bu işlemler her istekte ~80ms sürüyor!
Bir restoran düşün. Normalde her müşteri geldiğinde garson mutfağa gidip tarifi okuyor. OPcache Preloading ile en sık kullanılan tarifler garsonun cebinde hazır duruyor - mutfağa gitmeye gerek kalmıyor.
Teknik olarak: PHP başladığında belirli dosyalar memory'ye yükleniyor ve her istekte disk'ten okuma yerine direkt memory'den kullanılıyor.
1. Preload script oluştur:
<?php
require __DIR__.'/vendor/autoload.php';
// Laravel core sınıflarını preload et
$preloadClasses = [
\Illuminate\Foundation\Application::class,
\Illuminate\Container\Container::class,
\Illuminate\Support\ServiceProvider::class,
\Illuminate\Routing\Router::class,
\Illuminate\Http\Request::class,
\Illuminate\Http\Response::class,
// ... diğer sık kullanılan sınıflar
];
foreach ($preloadClasses as $class) {
if (class_exists($class)) {
// Sınıfı memory'ye yükle
}
}
2. PHP.ini'de aktif et:
opcache.preload = /var/www/vhosts/muzibu.com/httpdocs/preload.php opcache.preload_user = tuufi.com_
3. PHP-FPM yeniden başlat (kullanıcı yapmalı):
sudo systemctl restart php8.3-fpm
Öneri: Uygulanabilir, düşük risk. ~150ms → ~120-130ms beklenebilir. Ama dramatik bir fark yaratmaz. Plesk ortamında PHP.ini erişimi gerektirir.
Normalde her müşteri için yeni bir garson işe alınıyor, eğitiliyor, sonra kovuluyor. RoadRunner ile aynı garson sürekli çalışıyor - her seferinde eğitim yok, direkt hizmet.
Teknik olarak: Go ile yazılmış bir application server. PHP worker'ları canlı tutuyor, Laravel sadece bir kez bootstrap ediliyor.
Her istekte ~80ms bootstrap overhead
Bootstrap sadece 1 kez, sonra ~5-10ms/istek
1. Laravel Octane paketini kur:
composer require laravel/octane
2. RoadRunner'ı kur:
php artisan octane:install --server=roadrunner
3. Nginx'i RoadRunner'a yönlendir:
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
4. Systemd service oluştur (daemon olarak çalışsın):
[Unit] Description=Muzibu RoadRunner After=network.target [Service] User=tuufi.com_ WorkingDirectory=/var/www/vhosts/muzibu.com/httpdocs ExecStart=/usr/bin/php artisan octane:start --server=roadrunner --host=127.0.0.1 --port=8000 Restart=always [Install] WantedBy=multi-user.target
RoadRunner'da uygulama sürekli memory'de yaşıyor. Bu yüzden bazı kodlar sorun çıkarır:
class UserService {
private static $users = []; // Static değişken!
public function addUser($user) {
self::$users[] = $user; // Memory leak!
}
}
Static değişkenler istekler arası kalıcı olur → Memory leak
class UserService {
private array $users = []; // Instance değişkeni
public function addUser($user) {
$this->users[] = $user; // Her istekte yeni instance
}
}
⚠️ Muzibu için risk: Mevcut kodda static kullanımları, global state, singleton pattern'ler varsa hepsi gözden geçirilmeli. Multi-tenant yapı özellikle dikkat gerektirir!
Öneri: ~150ms → ~50-70ms beklenebilir. Ama multi-tenant yapı (Stancl/Tenancy) ve mevcut kod tabanı detaylı incelenmeli. Test ortamında önce denenmelidir.
RoadRunner gibi ama daha güçlü. Swoole PHP'yi Node.js gibi async/coroutine destekli hale getiriyor. Aynı anda binlerce bağlantı yönetebilir.
Teknik olarak: C ile yazılmış PHP extension. Event-driven, non-blocking I/O. PHP'nin çalışma modelini tamamen değiştiriyor.
| Özellik | RoadRunner | Swoole |
|---|---|---|
| Yazıldığı dil | Go | C (PHP extension) |
| Kurulum | Binary indir | PHP extension derle |
| Async I/O | Kısıtlı | Tam destek |
| Coroutines | Yok | Var |
| Concurrent bağlantı | ~10K | ~100K+ |
| Plesk uyumu | İyi | Zor |
| Kod değişikliği | Orta | Çok |
Aynı worker içinde binlerce "thread" çalışabilir. DB sorgusu beklerken başka işler yapılabilir.
Veritabanı sorguları non-blocking. 100 sorgu paralel çalışabilir.
Built-in WebSocket desteği. Real-time uygulamalar için ideal.
Worker'lar arası veri paylaşımı. Cache için harici servis gerekmez.
Öneri: Şu an için önerilmez. Plesk ortamında kurulum zor, multi-tenant yapıyla uyumluluk belirsiz. RoadRunner daha güvenli bir seçim.
| Çözüm | Performans | Zorluk | Risk | Tahmini Latency | Kod Değişikliği |
|---|---|---|---|---|---|
| Mevcut (PHP-FPM) | - | - | - | ~150ms | - |
| OPcache Preload | %10-20 | Kolay | Düşük | ~120-130ms | Yok |
| RoadRunner | %40-60 | Orta | Orta | ~50-70ms | Orta |
| Swoole | %50-70 | Zor | Yüksek | ~40-60ms | Çok |
Düşük risk, hızlı uygulama. %10-20 iyileşme sağlar.
Önce test ortamında dene. Multi-tenant uyumluluğunu kontrol et. Çalışırsa canlıya al.
Sadece RoadRunner yetmezse ve WebSocket gibi özellikler gerekirse değerlendir.
Not: ~150ms gecikme aslında çoğu Laravel uygulaması için "normal". HLS buffer ve queue preload sayesinde kullanıcı deneyimi zaten iyi. Optimizasyon yapmak güzel ama zorunlu değil.