Laravel Performance Optimizasyon

Swoole, RoadRunner ve OPcache Preloading Karşılaştırması

Mevcut Durum: PHP-FPM

Klasik PHP çalışma modeli

PHP-FPM Nasıl Çalışır?

İstek Geldi

Laravel Bootstrap

~80ms

Cevap Dön

Problem: Her istekte Laravel tamamen yeniden başlatılıyor:

  • • Tüm config dosyaları okunuyor
  • • Service container oluşturuluyor
  • • Service provider'lar boot ediliyor
  • • Facade'lar resolve ediliyor
  • • Middleware pipeline kuruluyor

Bu işlemler her istekte ~80ms sürüyor!

1. OPcache Preloading

Kolay Düşük Risk %10-20 İyileşme

Basit Anlatım

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.

Nasıl Yapılır?

1. Preload script oluştur:

# /var/www/vhosts/muzibu.com/httpdocs/preload.php
<?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

Avantajlar

  • ✅ Kolay kurulum (sadece config)
  • ✅ Kod değişikliği yok
  • ✅ Mevcut altyapıyla uyumlu
  • ✅ Düşük risk

Dezavantajlar

  • ❌ Sınırlı iyileşme (%10-20)
  • ❌ Kod değişikliğinde PHP-FPM restart gerekli
  • ❌ Memory kullanımı artar
  • ❌ Multi-tenant'ta dikkatli olunmalı

Muzibu İçin

Öneri: Uygulanabilir, düşük risk. ~150ms → ~120-130ms beklenebilir. Ama dramatik bir fark yaratmaz. Plesk ortamında PHP.ini erişimi gerektirir.

2. RoadRunner

Orta Zorluk Orta Risk %40-60 İyileşme

Basit Anlatım

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.

PHP-FPM vs RoadRunner

PHP-FPM (Şu anki)

İstek 1: Bootstrap Handle Kapat
İstek 2: Bootstrap Handle Kapat
İstek 3: Bootstrap Handle Kapat

Her istekte ~80ms bootstrap overhead

RoadRunner

Başlangıç: Bootstrap (1 kez)
İstek 1: Handle
İstek 2: Handle
İstek 3: Handle

Bootstrap sadece 1 kez, sonra ~5-10ms/istek

Kurulum Adımları

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

Dikkat! Kod Değişiklikleri Gerekli

RoadRunner'da uygulama sürekli memory'de yaşıyor. Bu yüzden bazı kodlar sorun çıkarır:

❌ Sorunlu Kod

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

✅ Doğru Kod

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!

Avantajlar

  • ✅ Dramatik performans artışı (%40-60)
  • ✅ Laravel Octane resmi destek
  • ✅ Go tabanlı, stabil
  • ✅ WebSocket desteği
  • ✅ Swoole'a göre daha kolay kurulum

Dezavantajlar

  • ❌ Kod değişikliği gerekli
  • ❌ Static/global state sorunları
  • ❌ Bazı paketler uyumsuz olabilir
  • ❌ Deploy süreci değişir
  • ❌ Debug zorlaşır

Muzibu İçin

Öneri: ~150ms → ~50-70ms beklenebilir. Ama multi-tenant yapı (Stancl/Tenancy) ve mevcut kod tabanı detaylı incelenmeli. Test ortamında önce denenmelidir.

3. Swoole

Zor Yüksek Risk %50-70 İyileşme

Basit Anlatım

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.

RoadRunner vs Swoole

Ö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

Swoole Ne Sağlar?

Coroutines

Aynı worker içinde binlerce "thread" çalışabilir. DB sorgusu beklerken başka işler yapılabilir.

Async MySQL/Redis

Veritabanı sorguları non-blocking. 100 sorgu paralel çalışabilir.

WebSocket Server

Built-in WebSocket desteği. Real-time uygulamalar için ideal.

Shared Memory

Worker'lar arası veri paylaşımı. Cache için harici servis gerekmez.

Avantajlar

  • ✅ En yüksek performans
  • ✅ Async/await desteği
  • ✅ Çok yüksek concurrency
  • ✅ Built-in WebSocket
  • ✅ Memory'de table/cache

Dezavantajlar

  • ❌ PHP extension derleme gerekli
  • ❌ Plesk ortamında zor
  • ❌ Çok fazla kod değişikliği
  • ❌ Debugging çok zor
  • ❌ Bazı paketler uyumsuz
  • ❌ Öğrenme eğrisi yüksek

Muzibu İçin

Öneri: Şu an için önerilmez. Plesk ortamında kurulum zor, multi-tenant yapıyla uyumluluk belirsiz. RoadRunner daha güvenli bir seçim.

Karşılaştırma Özeti

Çö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

Muzibu İçin Öneri

1

Kısa Vadede: OPcache Preloading

Düşük risk, hızlı uygulama. %10-20 iyileşme sağlar.

2

Orta Vadede: RoadRunner (Test Ortamı)

Önce test ortamında dene. Multi-tenant uyumluluğunu kontrol et. Çalışırsa canlıya al.

3

Uzun Vadede: Swoole (Opsiyonel)

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.

17 Şubat 2026 • Muzibu.com