Apache mod_deflate ile Gzip ve Brotli Sıkıştırma Yapılandırması

Web sunucunuzdan gelen her byte önemlidir. Kullanıcılarınız sayfaların hızlı yüklenmesini bekler, arama motorları site hızını sıralama faktörü olarak kullanır ve bant genişliği maliyetleriniz her geçen ay artmaya devam eder. İşte bu noktada HTTP sıkıştırma devreye girer. Apache’nin mod_deflate modülü, sunucunuzdan gönderilen içerikleri istemciye ulaşmadan önce sıkıştırarak hem kullanıcı deneyimini hem de sunucu performansını ciddi ölçüde iyileştirir. Bu yazıda mod_deflate ile Gzip ve Brotli sıkıştırmayı gerçek dünya senaryolarıyla birlikte ele alacağız.

Sıkıştırma Neden Bu Kadar Önemli?

Ortalama bir web sayfasının boyutu son yıllarda dramatik biçimde arttı. JavaScript kütüphaneleri, büyük CSS framework’leri, JSON API yanıtları… Bunların hepsi transfer edilmesi gereken veri anlamına gelir. Sıkıştırma olmadan 200KB’lık bir JavaScript dosyasını her istek için kullanıcıya gönderirsiniz. Gzip ile bu dosya genellikle 60-70KB’a düşer. Brotli ile daha da küçülür.

Gerçek bir örnek vermek gerekirse, bir müşterimin e-ticaret sitesinde sıkıştırma etkinleştirmeden önce ortalama sayfa ağırlığı 1.8MB civarındaydı. mod_deflate ve Brotli konfigürasyonunu düzenledikten sonra bu değer 420KB’a geriledi. Sayfa yüklenme süreleri özellikle mobil bağlantılarda yarı yarıya düştü.

mod_deflate Modülü Hakkında Temel Bilgiler

mod_deflate, Apache’nin yerleşik sıkıştırma modülüdür ve Gzip formatını kullanır. Adı biraz yanıltıcı olabilir çünkü “deflate” dediğimizde aslında zlib kütüphanesi üzerinden Gzip sıkıştırması yapılır. HTTP Accept-Encoding: gzip başlığını destekleyen tüm modern tarayıcılarla uyumlu çalışır.

Brotli ise Google tarafından geliştirilen ve özellikle statik web içerikleri için optimize edilmiş daha yeni bir sıkıştırma algoritmasıdır. mod_brotli modülü Apache 2.4.26 sürümünden itibaren resmi olarak desteklenmektedir.

Modüllerin Durumunu Kontrol Etme

Başlamadan önce hangi modüllerin yüklü olduğunu kontrol edelim:

# Yüklü modülleri listele
apache2ctl -M | grep -E "deflate|brotli|filter"

# Veya httpd kullananlar için
httpd -M | grep -E "deflate|brotli|filter"

# Modül dosyalarının varlığını kontrol et
ls -la /etc/apache2/mods-available/ | grep -E "deflate|brotli"

Çıktıda deflate_module (shared) ve brotli_module (shared) görüyorsanız modüller yüklü demektir. Eğer göremiyorsanız etkinleştirmeniz gerekir.

Modülleri Etkinleştirme

Ubuntu/Debian sistemlerde:

# mod_deflate etkinleştir
sudo a2enmod deflate

# mod_brotli etkinleştir (Apache 2.4.26+)
sudo a2enmod brotli

# mod_filter etkinleştir (sıkıştırma için gerekli)
sudo a2enmod filter

# Apache'yi yeniden başlat
sudo systemctl restart apache2

CentOS/RHEL/Rocky Linux sistemlerde modüller genellikle varsayılan olarak yüklüdür. Eğer Brotli yoksa paket deposundan kurmanız gerekebilir:

# RHEL/CentOS için mod_brotli genellikle ayrı pakette gelir
sudo dnf install mod_brotli

# Veya eski sistemlerde
sudo yum install mod_brotli

sudo systemctl restart httpd

Temel Gzip Konfigürasyonu

En basit haliyle mod_deflate konfigürasyonu şu şekilde görünür. Bu yapılandırmayı global Apache konfigürasyonuna, VirtualHost bloğuna veya .htaccess dosyasına ekleyebilirsiniz:

# /etc/apache2/mods-enabled/deflate.conf veya httpd.conf içine ekle

<IfModule mod_deflate.c>
    # Sıkıştırmayı etkinleştir
    SetOutputFilter DEFLATE
    
    # Sıkıştırma seviyeleri (1-9, 6 genellikle iyi denge noktasıdır)
    DeflateCompressionLevel 6
    
    # Belirli MIME türlerini sıkıştır
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/atom+xml
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE font/ttf
    AddOutputFilterByType DEFLATE font/otf
    AddOutputFilterByType DEFLATE font/woff
    AddOutputFilterByType DEFLATE application/font-woff
    AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
    
    # Zaten sıkıştırılmış dosyaları tekrar sıkıştırma
    SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png|webp|avif|mp4|mp3|ogg|zip|gz|bz2|rar)$ no-gzip dont-vary
    
    # Eski tarayıcılar için uyumluluk
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4.0[678] no-gzip
    BrowserMatch bMSIE !no-gzip !gzip-only-text/html
    
    # Proxy önbellekleme için Vary başlığı ekle
    Header append Vary Accept-Encoding
</IfModule>

DeflateCompressionLevel: 1 ile 9 arasında değer alır. 1 en hızlı ama en az sıkıştırma, 9 en fazla sıkıştırma ama en yavaş. 6 değeri genellikle CPU kullanımı ile sıkıştırma oranı arasında iyi bir denge sağlar.

SetEnvIfNoCase: Bu direktif sayesinde zaten sıkıştırılmış binary dosyaları (resimler, videolar, zip dosyaları) tekrar sıkıştırmaya çalışmıyoruz. Zaten sıkıştırılmış bir dosyayı tekrar sıkıştırmak hem CPU harcar hem de bazen dosyayı daha büyük yapabilir.

Brotli Konfigürasyonu

Brotli, modern tarayıcılar için Gzip’ten daha iyi sıkıştırma oranları sunar. Ancak daha fazla CPU kullanır, bu yüzden genellikle statik dosyalar için tercih edilir veya dinamik içerik için daha düşük sıkıştırma seviyesi kullanılır:

# /etc/apache2/conf-available/brotli.conf

<IfModule mod_brotli.c>
    # Brotli sıkıştırma kalitesi (0-11)
    # 11 en iyi sıkıştırma ama en yavaş
    # Dinamik içerik için 4-6 önerilir
    # Statik içerik için 6-11 kullanılabilir
    BrotliCompressionLevel 6
    BrotliCompressionWindow 22
    BrotliCompressionMaxInputBlock 16
    
    # MIME türlerine göre Brotli uygula
    AddOutputFilterByType BROTLI_COMPRESS text/html
    AddOutputFilterByType BROTLI_COMPRESS text/plain
    AddOutputFilterByType BROTLI_COMPRESS text/css
    AddOutputFilterByType BROTLI_COMPRESS text/javascript
    AddOutputFilterByType BROTLI_COMPRESS application/javascript
    AddOutputFilterByType BROTLI_COMPRESS application/json
    AddOutputFilterByType BROTLI_COMPRESS application/xml
    AddOutputFilterByType BROTLI_COMPRESS application/xhtml+xml
    AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
    AddOutputFilterByType BROTLI_COMPRESS font/ttf
    AddOutputFilterByType BROTLI_COMPRESS font/woff
    AddOutputFilterByType BROTLI_COMPRESS font/woff2
    
    # Vary başlığını güncelle
    Header append Vary Accept-Encoding
</IfModule>

Brotli konfigürasyonunu etkinleştirin:

sudo a2enconf brotli
sudo systemctl reload apache2

Gzip ve Brotli Birlikte Kullanmak

Gerçek dünyada her istemci Brotli desteklemez. Eski tarayıcılar, bazı API istemcileri veya curl gibi araçlar sadece Gzip destekleyebilir. Bu yüzden her iki yöntemi birlikte konfigüre etmek ve istemcinin Accept-Encoding başlığına göre doğru formatı sunmak gerekir.

Apache bu önceliklendirmeyi otomatik yapar. Accept-Encoding: br, gzip başlığı gönderen bir istemciye Brotli, sadece Accept-Encoding: gzip destekleyen birine Gzip gönderilir.

Daha granüler bir kontrol istiyorsanız mod_filter ile birlikte şu yaklaşımı kullanabilirsiniz:

<IfModule mod_filter.c>
    # Önce Brotli'yi dene, desteklenmiyorsa Gzip kullan
    <IfModule mod_brotli.c>
        FilterDeclare COMPRESS
        FilterProvider COMPRESS BROTLI_COMPRESS "%{req:Accept-Encoding} =~ /br/"
        FilterProvider COMPRESS DEFLATE "%{req:Accept-Encoding} =~ /gzip/"
        FilterChain COMPRESS
        FilterNote Input instream
        FilterNote Output outstream
        FilterNote Ratio ratio
    </IfModule>
</IfModule>

VirtualHost Bazında Konfigürasyon

Bazen farklı siteler için farklı sıkıştırma politikaları uygulamak gerekir. Örneğin, API sunucunuz için daha agresif sıkıştırma kullanabilir, statik dosya sunucunuz için farklı bir konfigürasyon tercih edebilirsiniz:

# API Sunucusu - Yüksek sıkıştırma
<VirtualHost *:443>
    ServerName api.orneksite.com
    DocumentRoot /var/www/api
    
    <IfModule mod_brotli.c>
        BrotliCompressionLevel 5
        AddOutputFilterByType BROTLI_COMPRESS application/json
        AddOutputFilterByType BROTLI_COMPRESS application/xml
        AddOutputFilterByType BROTLI_COMPRESS text/plain
    </IfModule>
    
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE application/json
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE text/plain
        DeflateCompressionLevel 7
    </IfModule>
    
    Header always append Vary Accept-Encoding
</VirtualHost>

# Statik Dosya Sunucusu - Önbellek ile birlikte
<VirtualHost *:443>
    ServerName static.orneksite.com
    DocumentRoot /var/www/static
    
    <IfModule mod_brotli.c>
        BrotliCompressionLevel 11
        AddOutputFilterByType BROTLI_COMPRESS text/css
        AddOutputFilterByType BROTLI_COMPRESS application/javascript
        AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
    </IfModule>
    
    # Statik dosyalar için uzun önbellekleme
    <FilesMatch ".(css|js|svg)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
</VirtualHost>

.htaccess ile Sıkıştırma

Paylaşımlı hosting ortamlarında veya uygulama bazında konfigürasyon için .htaccess dosyasını kullanabilirsiniz. AllowOverride All direktifinin etkin olması gerekir:

# .htaccess dosyası

<IfModule mod_deflate.c>
    # Metin tabanlı tüm içerikleri sıkıştır
    <FilesMatch ".(html|htm|php|css|js|json|xml|svg|txt)$">
        SetOutputFilter DEFLATE
    </FilesMatch>
    
    # Resim ve binary dosyaları hariç tut
    <FilesMatch ".(jpg|jpeg|png|gif|webp|ico|pdf|zip|gz)$">
        SetEnv no-gzip 1
    </FilesMatch>
</IfModule>

# Brotli desteği varsa kullan
<IfModule mod_brotli.c>
    <FilesMatch ".(html|htm|css|js|json|xml|svg|txt)$">
        AddOutputFilter BROTLI_COMPRESS
    </FilesMatch>
</IfModule>

Sıkıştırmayı Doğrulama ve Test Etme

Konfigürasyonun doğru çalıştığını doğrulamak için birkaç yöntem kullanabilirsiniz:

# curl ile Gzip kontrolü
curl -H "Accept-Encoding: gzip" -I https://orneksite.com/style.css

# curl ile Brotli kontrolü
curl -H "Accept-Encoding: br" -I https://orneksite.com/style.css

# Gerçek içeriği indirip boyutu karşılaştır
curl -o /dev/null -s -w "Boyut: %{size_download} byten" https://orneksite.com/style.css
curl -H "Accept-Encoding: gzip" -o /dev/null -s -w "Gzip boyutu: %{size_download} byten" https://orneksite.com/style.css
curl -H "Accept-Encoding: br" -o /dev/null -s -w "Brotli boyutu: %{size_download} byten" https://orneksite.com/style.css

# Ayrıntılı başlık bilgisi
curl -v -H "Accept-Encoding: gzip, deflate, br" https://orneksite.com/ 2>&1 | grep -i "content-encoding|vary|accept-encoding"

Yanıt başlıklarında Content-Encoding: gzip veya Content-Encoding: br görmek konfigürasyonun çalıştığını doğrular. Ayrıca Vary: Accept-Encoding başlığını da görmelisiniz.

Apache’nin sıkıştırma istatistiklerini kayıt altına almak için log formatını özelleştirebilirsiniz:

# httpd.conf veya apache2.conf içine ekle
DeflateFilterNote Input input_info
DeflateFilterNote Output output_info
DeflateFilterNote Ratio ratio_info

LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
CustomLog /var/log/apache2/deflate.log deflate

Bu sayede hangi isteklerin ne kadar sıkıştırıldığını log dosyasından takip edebilirsiniz.

Gerçek Dünya Senaryo: WordPress Sitesi Optimizasyonu

WordPress siteleri özellikle sıkıştırmadan büyük fayda görür. Tema dosyaları, plugin CSS/JS’leri ve dinamik HTML çıktısı sıkıştırma için ideal hedeflerdir. İşte tipik bir WordPress Apache konfigürasyonu:

<VirtualHost *:443>
    ServerName www.orneksite.com
    DocumentRoot /var/www/wordpress
    
    # SSL konfigürasyonu...
    
    <Directory /var/www/wordpress>
        AllowOverride All
        Require all granted
    </Directory>
    
    # Sıkıştırma konfigürasyonu
    <IfModule mod_brotli.c>
        BrotliCompressionLevel 6
        AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css
        AddOutputFilterByType BROTLI_COMPRESS application/javascript text/javascript
        AddOutputFilterByType BROTLI_COMPRESS application/json application/xml
        AddOutputFilterByType BROTLI_COMPRESS image/svg+xml font/woff font/woff2
    </IfModule>
    
    <IfModule mod_deflate.c>
        DeflateCompressionLevel 6
        AddOutputFilterByType DEFLATE text/html text/plain text/css
        AddOutputFilterByType DEFLATE application/javascript text/javascript
        AddOutputFilterByType DEFLATE application/json application/xml
        AddOutputFilterByType DEFLATE image/svg+xml font/woff font/woff2
        
        # Zaten sıkıştırılmış medya dosyalarını atla
        SetEnvIfNoCase Request_URI 
            .(?:gif|jpe?g|png|webp|avif|mp4|webm|mp3|ogg|zip|gz|bz2|rar|7z|pdf)$ 
            no-gzip dont-vary
    </IfModule>
    
    # Önbellek ve Vary başlıkları
    Header append Vary Accept-Encoding env=!dont-vary
    
    # WordPress için mod_expires
    <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresByType text/css "access plus 1 year"
        ExpiresByType application/javascript "access plus 1 year"
        ExpiresByType image/svg+xml "access plus 1 month"
    </IfModule>
    
    ErrorLog /var/log/apache2/wp-error.log
    CustomLog /var/log/apache2/wp-access.log combined
</VirtualHost>

Sık Karşılaşılan Sorunlar ve Çözümleri

Çift sıkıştırma problemi: PHP veya uygulama katmanı zaten sıkıştırma yapıyorsa Apache’nin tekrar sıkıştırması soruna yol açabilir. PHP ob_gzhandler veya Zend OPcache çıktı sıkıştırması aktifse Apache sıkıştırmasını devre dışı bırakın ya da PHP tarafındaki sıkıştırmayı kapatın.

Proxy arkasındaki sunucularda Vary başlığı: CDN veya reverse proxy kullanıyorsanız Vary: Accept-Encoding başlığının doğru iletildiğinden emin olun. Aksi takdirde kullanıcılar yanlış önbelleğe alınmış içerik alabilir.

Bazı içeriklerin sıkıştırılmaması: Eğer belirli MIME türleri sıkıştırılmıyorsa Apache’nin gerçekte hangi MIME türü gönderdiğini curl -v ile kontrol edin. Bazen application/javascript yerine text/javascript gibi farklı MIME türleri kullanılıyor olabilir.

ModSecurity ile çakışma: ModSecurity bazı durumlarda sıkıştırılmış içeriği inceleyemez. SecRequestBodyNoFilesLimit ve ilgili direktifleri kontrol edin.

Performans Değerlendirmesi

Sıkıştırma her zaman net kazanç sağlamaz. Bazı faktörler göz önünde bulundurulmalıdır:

  • Küçük dosyalar: 150 byte’tan küçük dosyaları sıkıştırmak anlamsızdır, hatta overhead nedeniyle daha büyük hale gelebilirler. Apache bu konuda genellikle otomatik karar verir.
  • CPU maliyeti: Yoğun trafik altında yüksek sıkıştırma seviyeleri (9 veya Brotli 11) CPU’ya yük bindirabilir. Dinamik içerik için orta seviyeler (5-7) tercih edilmelidir.
  • Önceden sıkıştırılmış dosyalar: Mümkünse .gz ve .br uzantılı dosyaları önceden üretip mod_negotiation veya direkt servis ederek CPU maliyetinden kaçınabilirsiniz.
  • Bant genişliği vs CPU tradeoff: Düşük bant genişlikli ortamlarda agresif sıkıştırma mantıklıdır. Yüksek bant genişliği olan veri merkezlerinde daha düşük seviyeler tercih edilebilir.

Konfigürasyonunuzu yaptıktan sonra Apache Benchmark ile test edebilirsiniz:

# Sıkıştırma olmadan test
ab -n 1000 -c 10 https://orneksite.com/

# Accept-Encoding başlığıyla test
ab -n 1000 -c 10 -H "Accept-Encoding: gzip" https://orneksite.com/

# Sonuçları karşılaştır: Transfer rate ve Time per request

Sonuç

mod_deflate ve mod_brotli konfigürasyonu Apache yönetiminin en kolay ama etkisi en yüksek optimizasyonlarından biridir. Gzip ile içerik boyutlarını genellikle yüzde 60-70 oranında küçültebilirsiniz, Brotli ile bu oran daha da iyiye gider. Konfigürasyon birkaç satır direktiften ibaretti ama etkisi çok büyük olabiliyor.

Yapılması gereken temel adımları özetlemek gerekirse: mod_deflate ve mod_brotli modüllerini etkinleştirin, metin tabanlı MIME türleri için sıkıştırmayı aktive edin, zaten sıkıştırılmış dosyaları hariç tutun, Vary başlığını doğru ayarlayın ve curl ile doğrulama yapın. Bu kadar.

Eğer henüz sıkıştırma kullanmıyorsanız, şu an sunucunuz gereksiz yere ekstra bant genişliği harcıyor demektir. Yukarıdaki konfigürasyonları kendi ortamınıza uyarlayın, Google PageSpeed Insights veya GTmetrix gibi araçlarla öncesi ve sonrasını karşılaştırın. Farkı görmek sizi şaşırtacak.

Yorum yapın