Sanal Makinada Apache EnableSendfile Sorunu

Apache ayarlarında EnableSendfile direktifi httpd'nin dosya iletimi için kernel sendfile desteğini kullanıp kullanmayacağını belirten bir değerdir.

Normal'de, özellikle css, js gibi statik dosyalarda, Apache bir isteğe cevap verirken dosyadaki verilere erişmesi gerekmiyor. sendfile destekleyen işletim sistemlerinde bu işlem dosyayı hiç okumadan gerçekleşebiliyor. Tabi ki bir kere okuyup buffer'lamış olması şartı ile.

Varsayılan değer on yani açık olduğu için ayarlara dokunmadıysanız bu desteği kullanıryorsunuz demektir.

Performans açısından getirisi büyük olabilir ama bazı durumlarda çok düzgün çalışmıyor. Bazen dosyayı düzenlemiş olmanıza rağmen değişikliği göremiyor olabilirsiniz. Hatta dosyadan bişeyler sildiyseniz dosyanın eski versiyonunun hatalı halini bile görebilirsiniz.

Sorun Olabilecek Durumlar

  • sendFile desteği düzgün çalışmayan platformlarda sorun yaşanıyor,
  • Linux tabanlı işletim sistemlerinde bazı network kartlarında IPv6 kullanırken TCP-checksum offloading bug'ının tetiklenmesine yol açabiliyor,
  • Itanium'da 2GB üzeri dosyalarda sorun yaşanıyor,
  • DocumentRoot dizini mount alanı olan durumlarda, kernel cache'inde sorun yaşanıyor.

Genel olarak geliştirme amaçlı kendi makinamızda bir dizini sanal makina içine mount (NFS ve SMB fark etmiyor) ederek çalıştığımız için en çok karşılaşılan senaryo sonuncusu oluyor.

Aşağıdaki örnekte css kodları biryerden sonra eksik yazılmış ama dosyaya baktığınızda aslında düzgün olduğunu görebilirsiniz.
sendFile açık olduğu durumda eksik hali Dosyanın içeriğinde düzgün hali

Nasıl Çözülür?

Bunu çözmenin çok kolay bir yolu var. Apache ayarlarından EnableSendfile değerini off olarak değiştirmek. Bu birçok şekilde yapılabilir. Aşağıda ki o yollardan sadece bir tanesi.

# sendfile seçeneğininin başındaki # işaretini kaldırıyoruz.
sudo sed -i 's/\#EnableSendfile/EnableSendfile/g' /etc/httpd/conf/httpd.conf
# on değerini off ile değiştiriyoruz. 
sudo sed -i 's/EnableSendfile on/EnableSendfile off/g' /etc/httpd/conf/httpd.conf

Yukarıkadi script bazı durumlarda çalışmayabilir. Bu durumda tek yapmanız gereken apache'nin konfigürasyonu içine EnableSendfile off yazmak. Bunu global olarak yapabileceğiniz gibi Directory direltifini kullanarak belirli dizinler için de kullanabilirsiniz.

Aşağıda ki örnek /my-nfs-file-path için sendfile kullanımını kapatıyor.

<Directory "/my-nfs-file-path">
...
EnableSendfile Off
...
</Directory>