İçindekiler
- 1 Ofiste Bir Trafik Dalgası ve Linux’un Derin Nefesi
- 2 Trafik Arttığında Kernel Ne Hisseder?
- 3 sysctl ile TCP: Uygulamayı Boğmadan Akışı Açmak
- 4 UDP Buffer’ları: DNS, Log ve Metriğin Sessiz Kahramanı
- 5 SYN Flood Gelirse Panik Yok: SYN Cookies ve synproxy
- 6 WordPress ve Laravel’de Pratik Bağlantılar: Nginx, PHP-FPM, Veritabanı
- 7 Ölç, Gözlemle, Küçük Adımlarla Yayına Al
- 8 Gerçek Hayattan Küçük Bir Senaryo
- 9 Kademeli Yayın ve Geri Dönüş Planı
- 10 Son Birkaç Pratik Dokunuş
- 11 Kapanış: Kernel’i Dinlemek, Trafiği Sakinleştirmek
Ofiste Bir Trafik Dalgası ve Linux’un Derin Nefesi
Hiç şöyle oldu mu? Normal günlerden biri, WordPress mağazasında kampanya başlıyor ya da Laravel API’niz bir uygulamada öne çıkıyor. Panelde trafik eğrisi usul usul yükseliyor derken bir anda duvara çarpıyorsunuz: site yavaş, API cevap vermiyor, loglarda zaman aşımı, grafikte 5xx hataları. O an fark ediyorsunuz; sunucu güçlü, kodunuz fena değil, ama işletim sistemi ağ katmanında nefesi kesilmiş. Ben de tam böyle bir gün, kahvem soğurken “kernel’a biraz alan açmanın” nelere kadir olduğunu yeniden gördüm.
Bu yazıda, yüksek trafikli WordPress ve Laravel uygulamalarında Linux TCP tuning dediğimiz ayarların nasıl hayata can verdiğini konuşacağız. sysctl tarafında backlog ve port aralığı gibi pratik ayarlar, UDP buffer’larını makul seviyeye çekmek, bir de beklenmedik anda kapıyı çalan SYN flood’a karşı panik yapmadan alınacak basit önlemler… Teknik detayları sıkmadan, gerçek hayattaki “mesela şöyle düşünün” örnekleriyle ilerleyeceğiz. Yolun sonunda, ölçeklenme anlarında OS katmanının sizin için nasıl bir güvenlik yastığına dönüştüğünü daha net göreceksiniz.
Trafik Arttığında Kernel Ne Hisseder?
Mesela bir WordPress kampanya sayfası düşünün. Herkes aynı anda geliyor, Nginx kuyruğu şişiyor, PHP-FPM süreçleri yoruluyor. Ama bu fotoğrafın arkasında kernel’in kabul kuyruğu, ağ sürücüsünün arabellekleri ve TCP’nin bağlantı işleyişi gibi gözle görünmeyen ama kritik katmanlar var. Sunucu sanki ön kapıda kalabalığı karşılayan bir güvenlik görevlisi gibi; kapıdan içeri kimleri alacağını, kimleri bekleteceğini, kimleri geri çevireceğini milisaniyeler içinde kararlaştırıyor. Kapı dar ise içeride her şey iyi olsa bile giriş tıkanıyor.
Bu yüzden OS katmanına dokunduğunuzda, aslında akışın en başındaki boğazı genişletmiş oluyorsunuz. Backlog değerleri “kapı önü kuyruğu” gibi çalışır. Ephemeral port aralığı istemci gibi davranan süreçler için “gidiş-dönüş şeritlerini” belirler. Keep-alive ayarları, tekrar tekrar kapıdan geçme masrafını azaltır. Ve elbette, dalga bir saldırıysa başka bir oyun planına ihtiyaç vardır. İşte o noktada SYN cookies ve synproxy gibi araçlar devreye girer.
sysctl ile TCP: Uygulamayı Boğmadan Akışı Açmak
İlk tavsiye: Ayarları körlemesine kopyalamayın. Ortam, trafik şekli, NIC, container kullanımı, hatta load balancer davranışı bu değerlerin “tatlı noktasını” değiştirir. Yine de şunu gördüm; bir dizi makul başlangıç değeri çoğu WordPress/Laravel iş yükünde nefes aldırıyor.
Backlog ve sırt çantası metaforu
Backlog’u, kapıdan içeri girmek için bekleyenlerin birikme alanı gibi düşünün. Nginx’teki accept kuyruğu dolarsa bağlantılar düşer. Kernel tarafında iki kritik yer var: net.core.somaxconn ve net.ipv4.tcp_max_syn_backlog. Birincisi kabul kuyruğunun üst sınırı, ikincisi ise “el sıkışma” aşamasındaki yarım bağlantıların tamponu. Trafiğin keskin dalgalar halinde geldiği WordPress kampanyalarında bu iki değerin cömert olması sıklıkla işe yarıyor.
TIME_WAIT, keep-alive ve tekrar kapıdan geçme masrafı
Kısa ömürlü bağlantılar TIME_WAIT birikimine yol açabilir. “Hep yeni bağlantı” demek, her seferinde kapıda kimlik kontrolü demek. Keep-alive ayarlarını mantıklı tutmak, web ve API tarafında ciddi rahatlama sağlar. Nginx’te keepalive bağlantılarının sayısını ve süresini dengeli ayarlarsınız, PHP-FPM tarafında da gereksiz kapat/aç döngüsünü azaltmış olursunuz. Bu sadece uygulamayı değil, kernel’i de rahatlatır.
Ephemeral port aralığı ve tünelin ferahlaması
Laravel tarafında üçüncü servislerle yoğun konuşan bir API düşünün. İstemci rolündeki süreçler için ayrılan geçici port aralığı dar ise, çıkış yönünde “yol bitti” uyarısı alırsınız. ip_local_port_range değerini biraz açmak, tünelin ferahlamasıdır. Özellikle NAT arkasında üst üste mikro servis çağrıları varsa bunu ihmal etmeyin.
Makul bir başlangıç dosyası
Aşağıdaki örnek, çoğu senaryoda işe yarayan, ama her ortamda test edilmesi gereken sakin bir başlangıç noktası. “Hafif büyük ama abartılı değil” diyebileceğimiz ayarlar.
# /etc/sysctl.d/99-tcp-tuning.conf
# Kabul kuyrukları ve NIC arabellekleri
net.core.somaxconn = 8192
net.core.netdev_max_backlog = 16384
# SYN aşamasındaki yarı-açık bağlantılar
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_synack_retries = 3
net.ipv4.tcp_syncookies = 1
# Kısa ömürlü bağlantılarda çabuk toparlanma
net.ipv4.tcp_fin_timeout = 15
# Keep-alive: uzun ömürlü ama makul
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
# Çıkış port aralığı: tüneli genişlet
net.ipv4.ip_local_port_range = 20000 60999
# MTU ve yavaş başlangıç davranışı
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_slow_start_after_idle = 0
# TCP buffer tavanları (UDP için de önemlidir)
net.core.rmem_default = 4194304
net.core.wmem_default = 4194304
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# Elde varsa, modern bir sıkışıklık kontrolü
# (Destekli mi bakmak için: sysctl net.ipv4.tcp_available_congestion_control)
net.ipv4.tcp_congestion_control = bbr
Bu dosyayı ekledikten sonra sysctl --system ile yükleyebilirsiniz. Elbette servislerinizin ayarlarıyla uyumlu olmalı; örneğin Nginx’te worker_connections ve keepalive limitleri çok küçükse, kernel tarafı tek başına mucize yaratmaz.
El sıkışmayı ucuzlatmak için küçük bir not
Trafiğiniz TLS ağırlıklıysa, ilk bağlantıların maliyeti artar. Bazı ortamlarda ikili sertifika yaklaşımı el sıkışmayı çevik kılar. Bu konuda Nginx/Apache tarafında pratik örnekler arıyorsanız, ikili SSL ile hem uyumluluğu hem hızı birlikte alma üzerine yazdığım rehber işinize yarayabilir.
UDP Buffer’ları: DNS, Log ve Metriğin Sessiz Kahramanı
“Benim sitem TCP, UDP ile ne işim olur?” diye düşünebilirsiniz. Gerçekte, işletim sistemi ve altyapı dünyasında UDP hayli meşgul. DNS sorguları, syslog, metrik toplayıcılar, izleme ajanları… Trafik yükseldiğinde bu küçük dalgaların tamponlarda sıkışması can sıkıcı gecikmelere yol açar. Özellikle DNS cevabında gecikme, tüm uygulama için gecikmedir.
UDP tarafında en sık yaptığım şey, çekirdek düzeyindeki genel buffer tavanlarını makul bir seviyeye taşımak. net.core.rmem_max ve net.core.wmem_max değerleri TCP kadar UDP için de üst sınırdır. Uygulamalar socket bazında kendi buffer’ını ayarlamaya çalıştığında bu tavanlara çarpar. Yukarıdaki örnekte 16 MB tavan, 4 MB varsayılan değerleri çoğu iş yükünde iyi bir dengedir. Aşırı yükseltmekse ters etki yaratabilir; çekirdek gereksiz yere büyük tamponlar taşır, bellek baskısı artar.
DNS tarafını bir adım daha güvenceye almak isterseniz, recursive resolver’ınızın kendi socket buffer ayarlarını da gözden geçirin. Sistem genelinin tavanı yükseldiyse, servis özelinde “ben de kullanayım” demesi gerekebilir. Ayrıca UDP için kernel’de üçlü bir eşik değeri daha vardır (udp_mem). Bu aile, sistem çapında toplam tampon kullanımıyla ilgilidir. Genellikle rmem/wmem tavanları mantıklıysa udp_mem’i ellemeye gerek kalmaz. Müdahale etmeniz gereken nadir senaryolarda ise önce gözlem, sonra küçük ve kontrollü adımlar iyi sonuç verir.
TCP/UDP parametrik davranışı konusunda kısa ve sade bir referans arıyorsanız, tcp(7) kılavuzundaki açıklamalar iyi bir dost gibidir. Biraz teknik dildir ama pratikte aradığınız çoğu soruya yanıt verir.
SYN Flood Gelirse Panik Yok: SYN Cookies ve synproxy
Bazen trafik dalgası masum değildir. Kapıda gerçek kullanıcı yoktur, sadece kapıyı meşgul eden yarı-açık bağlantılar vardır. Bu noktada tcp_syncookies hayat kurtarır. Kernel, el sıkışmayı hileli bir şeker gibi cebine koyar; kaynak tüketmeden karşı tarafın ciddiyetini ölçer. Basitçe, net.ipv4.tcp_syncookies = 1 çoğu sunucuda açık olmalı.
Daha sert dalgalarda ise L4/L7 tarafında bir ön savunma hattı kurmak iyi olur. synproxy, “tamam sen ciddisin, gel” demeden önce gelen SYN’leri sınar. Geleneksel iptables veya modern nftables ile uygulanabilir. Aşağıda bir nftables iskeleti görebilirsiniz. Elbette prod ortama almadan önce test edin.
# basit bir nftables synproxy iskeleti
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0; }
# Varsayılan izin/kurallarınız burada olsun...
# SYN paketlerini tespit et ve synproxy uygula
nft add rule inet filter input tcp flags syn tcp option maxseg size set 1460 synproxy mss 1460 wscale 7 timestamp sack-perm
# Bağlantının devamındaki paketlere izin ver
nft add rule inet filter input ct state established,related accept
synproxy’nin mantığını ve farklı kurulum şekillerini daha fazla incelemek isterseniz, nftables tarafındaki synproxy notları gayet açıklayıcıdır. Bir diğer pratik yaklaşım da trafiği bir L4/L7 yük dengeleyiciden geçirmek. Sağlıklı health check’ler ve akıllı zaman aşımı değerleriyle, dalgaları kıyıda kırıp uygulamaya yumuşatılmış trafik verirsiniz. Bu bağlamda HAProxy ile L4/L7 yük dengeleme üzerine anlattıklarımı göz atmalık bir rehber olarak önerebilirim.
İşin bir de connection tracking tarafı var. Eğer sunucunuz firewall/NAT nedeniyle conntrack kullanıyorsa, yoğun dalgalarda nf_conntrack_max sınırına çarpabilirsiniz. Bu durumda tablo boyutunu ölçülü bir şekilde büyütmek gerekir. Dikkat edin; bu ayar hafızayı doğrudan etkiler. “Çok açayım, rahat edeyim” demek her zaman işe yaramaz.
WordPress ve Laravel’de Pratik Bağlantılar: Nginx, PHP-FPM, Veritabanı
Tecrübe kısmına gelelim. WordPress ve Laravel’de en sık gördüğüm sorun, OS ve uygulama ayarlarının birbirini boğması. Kernel’de geniş backlog, ama Nginx’te düşük worker bağlantıları. Ya da Nginx keep-alive uzun ama PHP-FPM çok sıkılı. Uçlar aynı anda esnemezse arada yırtık oluşur.
Nginx tarafında keepalive_timeout ve keepalive_requests değerlerini, trafiğinizin doğasına göre ayarlayın. Eğer CDN veya reverse proxy arkasındaysanız, öndeki katmanın keep-alive davranışını da hesaba katın. Örneğin uzun süreli bağlantılar, el sıkışma maliyetini düşürür. Daha iyi anlaşılsın diye, Nginx timeout ve keep-alive dengesine dair pratikleri anlattığım yazıya göz atabilirsiniz; konseptler benzer.
PHP-FPM için havuz ayarları (pm, max_children, max_requests) ile TCP katmanının ritmi uyumlu olmalı. Çok kısa yaşamlı bağlantılar fazlaysa, kernel’deki TIME_WAIT birikimi artar. Bu durumda keep-alive ve HTTP/2 gibi adımlar nefes aldırır. Elbette, ön tarafta bir reverse proxy kullanmak genellikle hem OS hem uygulama için hayatı kolaylaştırır.
Laravel ve WordPress’in veritabanı ile konuşması ayrı bir dünya. Burada en verimli hamlelerden biri, bağlantı havuzu ve okuma-yazma ayrımı. Trafik dalgasında PHP süreçlerinin her seferinde yeni bağlantı açmasını beklemek, OS katmanında boşuna efor demektir. ProxySQL ile bağlantı havuzu ve read/write ayrımı üzerine anlattıklarım, WooCommerce ve Laravel için birebir pratik sağlar; bu sayede kernel’deki akış da daha pürüzsüz olur.
Ölç, Gözlemle, Küçük Adımlarla Yayına Al
Şimdi gelelim “nasıl yayına alacağım” sorusuna. Benim iş akışım genelde şöyle: önce mevcut durumu ölç. ss -s ile bağlantı durum dağılımına bak, netstat -s ile TCP istatistiklerini izle, mikro bir yük testi ile (örneğin wrk veya hey) trafiğin kabasını simüle et. Ardından, tek değişkeni oynat. Önce backlog, sonra keep-alive, sonra port aralığı… Her adımda tekrar ölç. Bu ritim, neyin işe yaradığını size fısıldar.
Uygulamalı bir örnek düşünün. WordPress kampanya sayfanız var. İlk turda net.core.somaxconn ile tcp_max_syn_backlog’u yükselttiniz, mini test yaptınız. İkinci turda Nginx keep-alive ayarlarını akışa göre uzattınız. Üçüncü turda ip_local_port_range değerini genişlettiniz. Dördüncü turda UDP buffer tavanlarını 4 MB/16 MB seviyelerine çektiniz. Her adımda ölçümler elinizde; zaman aşımı azaldı mı, 5xx düştü mü, p95 gecikme ne yaptı?
Bu işin belki de en görünmeyen yardımcısı TLS. İlk bağlantı maliyetini bir miktar yumuşatmak için, uygun gördüğünüz senaryolarda ECDSA ve RSA’yı birlikte kullanmanız faydalı olabilir. Burayı kurarken takıldığınızda, az önce paylaştığım ikili SSL yazısındaki pratikler adım adım yol gösterir.
“Savunma hattı” tarafına küçük bir hatırlatma daha: Bulut ya da edge katmanı kullanıyorsanız, oradaki timeout’lar ve keep-alive davranışları da paket akışınızı etkiler. Söz gelimi, CDN katmanınız uzun ömürlü bağlantıları severse, backend’inizin el sıkışma yükü azalır. Bu dengeyi kurarken, aradaki zincirin tüm halkalarını not edin.
Ek olarak, OS parametrelerinin davranışına dair daha teknik bir referans isterseniz, kernel’in ip-sysctl dokümantasyonunda sade ama işe yarar açıklamalar var. Ayarların yan etkilerini görmek için kısa notlar tutun; bir sonraki yayında kendi mini rehberiniz oluyorlar.
Gerçek Hayattan Küçük Bir Senaryo
Bir müşteride, Laravel tabanlı bir ödeme akışı ağırlaşmıştı. Grafiklerde düzensiz sıçramalar, loglarda “connect timeout” mesajları… İlk bakışta veritabanı yavaş sanılıyor. Oysa sorun, OS katmanında tıkanan kısa ömürlü bağlantılar ve yetersiz backlog. Önce sysctl tarafında kabul kuyruklarını genişlettik, SYN cookies’i teyit ettik. Sonra Nginx keep-alive ayarlarını uygulamanın ritmine uydurduk. Bir sonraki turda, ProxySQL ile küçük bir havuzlama yaptık. Sonuç, aynı kod ve aynı donanımla daha sakin bir akış. İşte bu yüzden diyorum; kernel’i dinlerseniz, çoğu zaman sorun çözülüyor.
Benzer bir hikaye WordPress’te. Kampanya günü, CDN arkasında olsak da backend bir süre sonra nefes nefese kalıyordu. Sorun, el sıkışma sırasında oluşan birikme ve UDP tarafında log/metrik kuyruğunun daralması. UDP buffer tavanlarını yükselttik, TLS tarafında ikili sertifika yaklaşımıyla el sıkışmaları yumuşattık, ve ön tarafta L4/L7 yük dengelemede health check’leri daha akıllı hale getirdik. Dalgalar kıyıya çarptı ama bina sağlam kaldı.
Kademeli Yayın ve Geri Dönüş Planı
İşletim sistemi ayarları, canlı ortamda “hemen ve büyük” değişiklikleri sevmez. Küçük artışlar, net ölçümler, gerektiğinde adım geri… Bu üçlü rahat ettirir. Eğer birden fazla node varsa, ayarları tek tek, farklı zamanlarda uygulayın. Beklenmedik yan etki görürseniz, hızlı geri dönüş için orijinal dosyayı kenarda tutun. Bir de unutmadan: container’lı ortamlarda host kernel ayarları ile pod/container limitleri birlikte düşünülmeli. Sadece sysctl ile değil, servislerin kendi socket ayarlarıyla da uyum şart.
Uygulama katmanında kuyruk kullanıyorsanız, işleyicilerin bağlantı davranışını da gözleyin. Örneğin yoğun job’lar kısa ömürlü ama çok sayıda dış istek yapıyorsa, keep-alive ve havuzlama ile OS tarafındaki yükü ciddi azaltabilirsiniz. Bu sadece performans değil, hata oranlarını da etkiliyor.
Son Birkaç Pratik Dokunuş
Gözleme yardımcı birkaç komut: ss -s bağlantı durum özetini verir, ss -tan ile anlık yoğunluğu görürsünüz. netstat -s TCP istatistiklerini serer; retransmission artıyorsa bir yerde tıkanma ya da paket kaybı olabilir. dmesg ve sistem log’ları, buffer baskısını ele verir. htop ile softirq baskısı hissediyorsanız, NIC sürücüsü ve IRQ dağılımını da kontrol etmek gerekebilir; ama bu konu ayrı bir yazı ister.
Edge ya da proxy katmanı kullanıyorsanız, backend’le tutarlı timeout’lar kritik. Uygulama 60 saniyede pes ederken CDN 15 saniyede bırakıyorsa, kullanıcı deneyimini CDN belirler. Bu senaryolarda, daha önce paylaştığım HAProxy sağlık kontrolü ve timeout dengesini tekrar hatırlatmak isterim. Aynı şekilde, uzun soluklu oturumlarda keep-alive ve bağlantı ömrü üzerine notlar orada.
Trafik kampanyalarında TLS yenileme/sertifika limitleri gibi dolaylı noktalar bile akışı etkileyebiliyor. Hatta bazen sırf bu yüzden kullanıcılar yeniden deniyor, dalga büyüyor. Böyle senaryolarda, altyapının diğer taşlarını da düşünmek güzel olur. Her şey birbirini etkiliyor.
Kapanış: Kernel’i Dinlemek, Trafiği Sakinleştirmek
Toparlayalım. WordPress ya da Laravel uygulamanız nefes nefese kaldığında, çoğu zaman ilk akla gelen kod ve veritabanı oluyor. Oysa bir adım altta, Linux’un TCP/UDP ayarları trafik dalgalarını yumuşatan gizli kahraman. Backlog’u mantıklı seviyede tutmak, keep-alive ile “tekrar kapıdan geçme” maliyetini azaltmak, ephemeral port aralığını genişletmek ve UDP buffer’larını makul yükseltmek fark yaratıyor. İş büyüyüp saldırı kokusu taşıyorsa, SYN cookies ve gerektiğinde synproxy devreye giriyor; nftables synproxy notlarına göz atmak iyi fikir.
Pratik tavsiye: Küçük oyna, çok ölç, hızlı geri dön. Ayar dosyanı versiyonla, her değişikliği not düş. Dalgalar geldiğinde, önce kapıdaki kuyrukları ve el sıkışma davranışını kontrol et. Ardından uygulama ve veritabanı katmanına bak. Ve eğer veritabanı bağlantılarında esneklik istiyorsan, bağlantı havuzu ile okuma-yazma ayrımı gibi dokunuşlarla işi daha da konforlu hale getirebilirsin.
Umarım bu yazı, trafik yükseldiğinde nereden başlayacağınıza dair sakin bir yol haritası sunmuştur. Kafanıza takılan bir ayar olursa, küçük bir test ortamında deneyip sonuçları birlikte yorumlamak her zaman mümkün. Bir dahaki yazıda görüşmek üzere; log’larınız sakin, bağlantılarınız sağlıklı olsun.
