Yazılara geri dön
Yazı

tc ile Ağ Gecikmesi Enjekte Ederek Pre‑Prod Testi Yapma

Linux tc aracılığıyla gecikme, jitter ve paket kaybı simüle ederek üretime öncesi uygulama dayanıklılığınızı test edin. Komut örnekleri ve temizlik ipuçlarıyla.

Networktcnetemlatency testingtraffic control

Uygulamanın kötü ağ koşullarında nasıl davrandığını test etmek, canlı ortamlara değişiklik poussermeden önce rutin olarak yaptığım şeylerden biridir. Tahmin yapmak veya belirsiz staging kurulumlarına güvenmek yerine, Linux'a yerleşik olan tc (traffic control) alt sistemini kullanarak istediğim anda gecikme, jitter ve paket kaybı enjekte ederim. Böylece, gerçek donanıma gerek kalmadan yüksek gecikmeli bölge間i bağlantılar veya tıkanan son mil bağlantıları gibi kenar durumlarını yeniden üretebilirim.

Buradaki temel araç, iproute2 paketinin parçası olan tc komutudur. Bu komut, bir ağ arayüzüne queueing discipline (qdisc) ekleyerek çalışır. Gecikme simülasyonu için en yaygın kullanılan qdisc netem'dir, yani "network emulator'un kısaltması. netem ile sabit gecikme, değişken gecikme (jitter), paket çoğaltması, bozulma ve daha fazlasını ekleyebilirim.

Örneğin, web API'mın 150ms dönüş gecikmesini nasıl işlediğini test etmek istiyorum. İlk olarak arayüzü belirlerim—genellikle VM'de eth0 veya ens5 olur—ve ardından bir netem kuralı uygularım:

sudo tc qdisc add dev eth0 root netem delay 150ms

Bu komuttan sonra, eth0'dan çıkan tüm trafiğe ekstra 150ms gecikme yaşanır. Başka bir host'tan ping ile bunu doğrulayabilirim:

$ ping -c 5 10.0.0.5
PING 10.0.0.5 (10.0.0.5) 56 data bytes
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=150.2 ms
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=150.1 ms
64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=150.3 ms

Bu çıktı, gecikmenin aktif olduğunu doğrular. Ancak gerçek ağlar完全に均一 değildir—jitter vardır. Bunun simülasyonu için bir dağılım eklerim. Örneğin, normal dağılımla 150ms ± 30ms:

sudo tc qdisc change dev eth0 root netem delay 150ms 30ms distribution normal

Şimdi ping zamanları 150ms civarında değişecek ve gerçek dünya değişkenliğini taklit edecek. Mikroservislerde timeout mantığını veya istemci SDK'larında yeniden deneme mekanizmalarını test ederken bu özellikle yararlı buluyorum.

Bazen gecikmeyi aşarak paket kaybı test etmem gerekebilir. Belki uygulamam çelik 4G bağlantısı veya uydu bağlantısı üzerinden çalışıyor. Kaybı eklemek basittir:

sudo tc qdisc change dev eth0 root netem delay 150ms 30ms loss 5%

Bu komut, gecikmeli ve jitterli bağlantıya ek olarak %5 rastgele paket kaybı enjekte eder. Bu kombinasyonu, yeniden iletimi düzgün şekilde işlemeyen HTTP istemcilerindeki hataları veya bitrate'i zarif bir şekilde düşüemeyen video akışı adaptörlerindeki sorunları ortaya çıkarmak için kullanıyorum.

Bir arayüzde şu anda uygulanan kuralı görmek istersem şöyle bakarım:

sudo tc qdisc show dev eth0

Çıktı şuna benzer olabilir:

qdisc netem 8001: root refcnt 2 limit 1000 delay 150.0ms 30.0ms loss 5% 0%

Testi tamamladığımda, normal ağ davranışını geri getirmek için kuralı temizlerim:

sudo tc qdisc del dev eth0 root

Bu temizlemeyi yapmak önemlidir—bazı bulut görüntülerinde kalan tc kuralları yeniden başlatılarda kalabilir ve daha sonra karıştırıcı performans sorunlarına yol açabilir. Eski bir netem kuralının unutulan bir testten hâlâ aktif olması nedeniyle "gizemli gecikme" üzerine saatlerce zaman kaybettiği takımları gördüm.

Daha karmaşık senaryolar için, örneğin yukarı akış ve aşağı akış arasında farklı gecikme olan asimetrik bağlantıları simüle etmek istersem, ifb (Intermediate Functional Block) cihazlarını kullanarak her iki yönde de trafik şekillendiririm. Ancak çoğu pre‑prod doğrulama—özellikle API timeout'ları, frontend yükleme davranışı veya stres altında veritabanı bağlantı havuzu testi—için, sunucu veya istemci VM'de basit çıkış gecikmesi genellikle yeterlidir.

Bu yöntemi, iftop, nload gibi izleme araçlarıyla veya uygulama seviyesindeki metriklerle (yanıt süreleri, hata oranları) birleştirerek etkisini gerçek zamanlı olarak gözlemlemeyi de severim. Kernel CPU sorunlarını gidermeyle ilgili önceki yazımda da belirttiğim gibi, gözlevilebilirlik mevcut olduğunda yavaşlamaların enjekte edilmiş ağ sorunlarından mı yoksa başka bir şeyden mi kaynaklandığını ayıklamak daha kolay olur.

Pratik bir ipucu: konteyner içinde test yapıyorsanız, konteyneri --net=host ile çalıştırmalı ya da host ad alanından veth çiftini hedefleyerek tc kuralı uygulamalısınız. Docker ve Kubernetes, varsayılan olarak ayrıcalık kısıtlamaları nedeniyle konteyner içinde tc'yi değiştirmenize izin vermez.

Son olarak, bu değişiklikleri her zaman önce üretim dışı bir ortamda test edin. tc güvenli ve geri alınabilir olsa da, canlı bir hizmette ağır kaybı veya gecikmeyi uygulamak zincirlenme hatalarına veya izleme sistemlerinde yanlış alarmlara yol açabilir.

Uygulama dayanıklılığınızı doğruluyorsanız, gerçek ağ koşullarını tc ile simüle etmek, düşük maliyetli ve etkili yöntemlerden biridir. Soyut "what if" sorularını somut, tekrarlanabilir testlere dönüştürür.


Kapak görseli: ₡ґǘșϯγ Ɗᶏ Ⱪᶅṏⱳդ · CC0 (Openverse / kamu malı) · https://www.flickr.com/photos/148598741@N02/53210652349