Web sunucunuzun performansı düşüyor, kullanıcılar zaman zaman timeout hataları alıyor ya da sunucunuz gereksiz yere çok kaynak tüketiyor mu? Bunların büyük çoğunluğunun arkasında yanlış yapılandırılmış Timeout ve KeepAlive parametreleri yatıyor. Apache’nin bu iki kritik ayarını doğru yapmak, hem sunucu stabilitesi hem de son kullanıcı deneyimi açısından inanılmaz fark yaratıyor. Bu yazıda bu parametreleri derinlemesine inceleyeceğiz, gerçek dünya senaryolarıyla ne zaman nasıl ayarlama yapmanız gerektiğini ele alacağız.
Timeout ve KeepAlive Nedir, Neden Önemlidir?
Önce temel kavramları netleştirelim. Apache’de Timeout direktifi, bir isteğin tamamlanması için sunucunun ne kadar bekleyeceğini saniye cinsinden belirler. Bu süre dolduğunda Apache bağlantıyı keser ve kaynakları serbest bırakır. KeepAlive ise HTTP/1.1 ile gelen kalıcı bağlantı özelliğidir; tek bir TCP bağlantısı üzerinden birden fazla istek gönderilmesine olanak tanır.
Neden bu kadar kritik? Çünkü her yanlış ayar farklı bir soruna yol açar:
- Timeout çok düşükse: Yavaş istemciler veya büyük dosya yüklemeleri sürekli kesilir
- Timeout çok yüksekse: Yavaş saldırılar (Slowloris gibi) sunucunuzu çökertir
- KeepAlive kapalıysa: Her kaynak için ayrı TCP bağlantısı açılır, gecikme artar
- KeepAlive açık ama yanlış ayarlıysa: Bağlantılar gereksiz yere açık kalır, işçi süreçler tükenir
Apache Timeout Direktifleri
Apache’de tek bir “Timeout” değeri yoktur aslında. Birkaç farklı direktif farklı senaryoları kontrol eder.
Temel Timeout Direktifi
# /etc/apache2/apache2.conf veya httpd.conf
Timeout 300
Bu değer varsayılan olarak 300 saniyedir ve şu üç durumu kapsar:
- İstemciden bir GET isteğinin alınmasını bekleme süresi
- POST/PUT isteğinde TCP paketleri arasındaki maksimum bekleme süresi
- İstemciye TCP yanıt paketleri arasındaki maksimum bekleme süresi
300 saniye çoğu senaryo için fazlasıyla uzun. Genel bir web uygulaması için 60-120 saniye çok daha makul bir başlangıç noktasıdır.
RequestReadTimeout ile Daha İnce Kontrol
Apache 2.2.15 ve sonrasında gelen mod_reqtimeout modülü, istek okuma sürecini çok daha ayrıntılı yönetmenizi sağlar. Bu modül varsayılan olarak etkin gelir ama çoğu yönetici varlığından bile habersizdir.
# mod_reqtimeout aktivasyonu kontrolü
apache2ctl -M | grep reqtimeout
# Etkin değilse aktive edin
a2enmod reqtimeout
RequestReadTimeout direktifinin söz dizimi biraz karmaşık görünebilir ama mantığını kavradığınızda çok güçlü bir araç olduğunu anlarsınız:
# /etc/apache2/conf-available/reqtimeout.conf
# Header okuma: minimum 20 saniye, sonra her 500 byte için 1 saniye ekle, max 40 saniye
RequestReadTimeout header=20-40,MinRate=500
# Body okuma: minimum 10 saniye, sonra her 500 byte için 1 saniye ekle, max 120 saniye
RequestReadTimeout body=10,MinRate=500
Bu yapılandırma şu anlama geliyor: Header için en az 20 saniye ver, ama istemci saniyede en az 500 byte veri gönderiyorsa süreyi uzat, toplamda 40 saniyeyi geçme. Body için de benzer mantık geçerli.
Slowloris Saldırılarına Karşı Timeout Optimizasyonu
Slowloris, çok yavaş HTTP başlıkları göndererek Apache işçilerini meşgul eden bir DDoS saldırısıdır. Doğru Timeout ayarları bu saldırıya karşı önemli bir savunma katmanı oluşturur:
# /etc/apache2/conf-available/security-timeouts.conf
# Çok agresif ama saldırıya açık sistemler için
RequestReadTimeout header=10-20,MinRate=500
RequestReadTimeout body=10,MinRate=500
Timeout 60
# Bu ayarı da aktive edin
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
Değişiklikleri uygulamak için:
# Konfigürasyonu test edin
apachectl configtest
# Apache'yi yeniden yükleyin (downtime olmadan)
systemctl reload apache2
KeepAlive Ayarları
KeepAlive Neden Önemli?
Modern bir web sayfası açtığınızda tarayıcı onlarca, bazen yüzlerce kaynak yükler: CSS dosyaları, JavaScript, görseller, fontlar… KeepAlive kapalıysa her biri için ayrı bir TCP el sıkışması gerekir. Bu da hem gecikme hem de kaynak tüketimi açısından ciddi bir maliyet demektir.
Temel KeepAlive Yapılandırması
# /etc/apache2/apache2.conf
# KeepAlive'ı etkinleştir
KeepAlive On
# Tek bir bağlantıda kaç istek yapılabilir
MaxKeepAliveRequests 100
# Bağlantı boşta kalırsa kaç saniye bekle
KeepAliveTimeout 5
Bu üç direktif birlikte çalışır. Tek tek inceleyelim:
KeepAlive On/Off: Kalıcı bağlantıları açıp kapatır. Neredeyse her senaryoda On olmalı.
MaxKeepAliveRequests 100: Bir bağlantı üzerinden maksimum 100 istek yapılabilir. 0 değeri sınırsız demektir ama bunu yapmayın. 100-200 arası değerler çoğu uygulama için idealdir. Yüksek trafikli statik içerik sunan sunucular için 200-500 düşünülebilir.
KeepAliveTimeout 5: Bağlantı 5 saniye boşta kalırsa kapat. Bu değer kritik. Çok yüksek tutarsanız işçi süreçleriniz boşta bekleyen bağlantılarla dolar.
KeepAliveTimeout İçin Gerçekçi Değerler
Pek çok sysadmin bu değeri 15-30 saniye olarak bırakır ve ciddi performans sorunları yaşar. Araştırmalar ve gerçek dünya deneyimleri şunu gösteriyor:
- 1-2 saniye: Çok agresif, yüksek trafikte sorun olmaz ama bazı yavaş bağlantılarda sorun çıkabilir
- 5 saniye: Çoğu senaryo için ideal başlangıç noktası
- 10 saniye: Makul ama işçi tüketimini artırır
- 15+ saniye: Yüksek trafikli sunucularda felaket reçetesi
Virtual Host Bazında KeepAlive Ayarı
Farklı uygulamalarınız farklı davranış gerektirebilir. Örneğin API endpoint’leri için KeepAlive daha az anlamlıyken, görselli içerik sunan bir site için çok değerlidir:
# /etc/apache2/sites-available/static-content.conf
<VirtualHost *:443>
ServerName static.orneksite.com
# Statik içerik için yüksek KeepAlive değerleri mantıklı
KeepAlive On
MaxKeepAliveRequests 200
KeepAliveTimeout 10
DocumentRoot /var/www/static
</VirtualHost>
# /etc/apache2/sites-available/api-backend.conf
<VirtualHost *:443>
ServerName api.orneksite.com
# API için daha kısa timeout
KeepAlive On
MaxKeepAliveRequests 50
KeepAliveTimeout 2
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
MPM (Multi-Processing Module) ile Timeout İlişkisi
Timeout ve KeepAlive ayarları tek başına yeterli değil. Bu değerlerin MPM yapılandırmanızla uyumlu olması gerekiyor. Aksi takdirde tüm optimizasyonlarınız boşa gider.
Prefork MPM ile Optimizasyon
# /etc/apache2/mods-available/mpm_prefork.conf
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
Prefork’ta her işçi bir bağlantıya atanır. Bu yüzden KeepAliveTimeout değeri doğrudan kaç işçinin boşta beklediğini etkiler. MaxRequestWorkers 150 ise ve her bağlantı 15 saniye KeepAlive bekliyorsa, düşük trafikte bile işçileriniz hızla tükenir.
Worker veya Event MPM ile Optimizasyon
# /etc/apache2/mods-available/mpm_event.conf
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
Event MPM, KeepAlive bağlantılarını ayrı bir “dinleyici” thread’de tutabildiği için prefork’a göre çok daha verimlidir. Bu MPM kullanıyorsanız KeepAliveTimeout değerini biraz daha yüksek tutabilirsiniz, örneğin 5-10 saniye.
Hangi MPM kullandığınızı kontrol etmek için:
apachectl -V | grep -i mpm
# veya
apache2ctl -M | grep mpm
Gerçek Dünya Senaryoları
Senaryo 1: E-ticaret Sitesi
Müşteri sayfayı açtığında onlarca ürün görseli, CSS, JS yükleniyor. Checkout sayfasında büyük form POST’ları var, ödeme işlemi bazen 10-15 saniye sürüyor.
# /etc/apache2/sites-available/eticaret.conf
<VirtualHost *:443>
ServerName magazam.com
# Genel ayarlar
KeepAlive On
MaxKeepAliveRequests 150
KeepAliveTimeout 5
Timeout 120
# Ödeme sayfası için ayrı timeout (location bazında)
<Location /checkout/payment>
Timeout 300
</Location>
# Yükleme endpoint'i için
<Location /admin/upload>
Timeout 600
</Location>
# mod_reqtimeout ayarları
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=20-40,MinRate=500
RequestReadTimeout body=30,MinRate=500
</IfModule>
</VirtualHost>
Senaryo 2: Yüksek Trafikli Haber Portalı
Saniyede yüzlerce istek, çoğu HTML sayfa okuma. Uzun süreli bağlantılar sunucu kaynaklarını tüketiyor.
# Yüksek trafik için agresif ayarlar
<VirtualHost *:80>
ServerName haber.orneksite.com
KeepAlive On
MaxKeepAliveRequests 100
# Haber siteleri için 2-3 saniye yeterli
KeepAliveTimeout 3
Timeout 60
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=10-20,MinRate=500
RequestReadTimeout body=10,MinRate=500
</IfModule>
# Gzip ile birlikte çalışırken
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/javascript
</IfModule>
</VirtualHost>
Senaryo 3: Reverse Proxy Arkasında Uygulama Sunucusu
Apache, arkasında bir Tomcat veya Node.js uygulamasına proxy yapıyor. Bu senaryoda ProxyTimeout da devreye giriyor:
# /etc/apache2/sites-available/app-proxy.conf
<VirtualHost *:443>
ServerName app.orneksite.com
# Apache istemci bağlantısı için
KeepAlive On
KeepAliveTimeout 5
Timeout 120
# Proxy timeout ayarları - backend'in cevap süresine göre ayarla
ProxyTimeout 90
# Proxy bağlantı havuzu
<Proxy balancer://appcluster>
BalancerMember http://10.0.0.10:8080
BalancerMember http://10.0.0.11:8080
</Proxy>
ProxyPass / balancer://appcluster/
ProxyPassReverse / balancer://appcluster/
# Backend bağlantısını keepalive ile tut
ProxyPassMatch ^/(.*) http://10.0.0.10:8080/$1
<Proxy *>
ProxySet keepalive=On
ProxySet timeout=90
ProxySet connectiontimeout=10
</Proxy>
</VirtualHost>
Performans Testleri ile Doğrulama
Ayarları yaptınız, peki doğru mu? Test etmeden bilemezsiniz. ab (Apache Benchmark) ile hızlı bir test yapabilirsiniz:
# 1000 istek, 100 eş zamanlı bağlantı, KeepAlive ile
ab -n 1000 -c 100 -k https://orneksite.com/
# KeepAlive olmadan aynı test
ab -n 1000 -c 100 https://orneksite.com/
# Sonuçları karşılaştırın, özellikle şu değerlere bakın:
# - Requests per second
# - Time per request
# - Transfer rate
Apache’nin durumunu izlemek için mod_status çok kullanışlıdır:
# mod_status etkinleştirme
a2enmod status
# /etc/apache2/mods-available/status.conf
<Location /server-status>
SetHandler server-status
Require ip 127.0.0.1 10.0.0.0/24
</Location>
# Canlı izleme
watch -n 1 'curl -s http://localhost/server-status?auto | grep -E "BusyWorkers|IdleWorkers|Waiting|Reading|Writing"'
Log Analizi ile Sorun Tespiti
Timeout sorunlarını tespit etmenin en iyi yolu log analizidir:
# Timeout alan istekleri tespit et
grep "408" /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head 20
# Çok uzun süren istekler (request time'ı loglamak için önce formatı ayarlayın)
# LogFormat'a %T (saniye) veya %D (mikrosaniye) ekleyin:
LogFormat "%h %l %u %t "%r" %>s %b %T" combined_with_time
# 10 saniyeden uzun süren istekler
awk '$NF > 10' /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -rn
Daha detaylı bir log formatı için:
# /etc/apache2/apache2.conf
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i" %T/%D" performance
CustomLog /var/log/apache2/performance.log performance
Sık Yapılan Hatalar ve Çözümleri
Hata 1: KeepAliveTimeout’u çok yüksek tutmak
Birçok yönetici varsayılan değeri 15 saniye görüyor ve olduğu gibi bırakıyor. Yoğun trafikte bu işçi açlığına yol açar. İzleme yapın ve gerçek değerlere göre karar verin.
Hata 2: Timeout’u global tutup location bazında özelleştirmemek
Her endpoint aynı timeout değerini gerektirmez. Upload endpoint’leri, ödeme sayfaları, rapor oluşturma işlemleri daha uzun timeout’a ihtiyaç duyar.
Hata 3: mod_reqtimeout’u görmezden gelmek
Bu modül hem güvenlik hem performans açısından kritik. Kurulum sonrası aktif olmayan sunucularda Slowloris’e açık kapı bırakabilirsiniz.
Hata 4: MPM ile uyumsuz KeepAlive ayarları
Prefork kullanıyorsanız KeepAliveTimeout değerini düşük tutun. Event MPM’e geçiş yapmanız bu konuda size çok daha fazla esneklik sağlar.
Hata 5: ProxyTimeout’u unutmak
Reverse proxy senaryolarında Apache’nin kendi Timeout’unu ayarlayıp backend ProxyTimeout’unu unutmak çok yaygın. Her ikisini de yapılandırın.
Sonuç
Apache’de Timeout ve KeepAlive optimizasyonu tek seferlik bir iş değil, sürekli izleme ve ayarlama gerektiren bir süreç. Şu ana kadar anlattıklarımı özetleyecek olursak: Timeout’u 300 saniyeden 60-120 saniyeye indirmek birinci adımınız olmalı. RequestReadTimeout direktifini Slowloris saldırılarına karşı aktive edin. KeepAliveTimeout’u 5 saniye olarak başlatın, sunucunuzu izleyin ve trafiğinize göre ince ayar yapın.
Kullandığınız MPM’i bilerek bu değerleri ayarlamak çok önemli. Prefork’ta her boşta bağlantı bir işçiyi tutuyor; Event MPM’e geçiş yapabiliyorsanız hem KeepAlive yönetimi hem de genel performans açısından ciddi kazanım elde edersiniz.
Son olarak, herhangi bir değişikliği önce test ortamında deneyin, ab ile yük testi yapın, mod_status ile gerçek zamanlı izleme kurun ve loglarınızı analiz edin. Sunucu yönetimi sonuçta veri odaklı karar alma sürecidir. Sezgiyle değil, gözlemle optimize edin.