Eğitim seçeneklerini yan yana koyup karar verin

Rate Limiting Implementasyonu: Token Bucket ve Sliding Window

Rate Limiting Nedir ve Neden Gereklidir?

API'ler modern uygulamaların omurgasıdır, ancak sınırsız isteklere açık bırakılan bir API hızla çöküp kullanıcılarını hayal kırıklığına uğratır. Rate limiting, belirli bir zaman diliminde bir kaynaktan gelen isteklerin sayısını kontrol eden bir güvenlik ve performans mekanizmasıdır. Bir sunucuya dakikada kaç istek yapılabileceğini belirlemek, DoS saldırılarını önlemekten tutun da kaynakları adil şekilde paylaştırmaya kadar pek çok amaca hizmet eder.

Rate limiting implementasyonu, tek bir sunucudan daha karmaşıktır. Özellikle mikroservisler mimarisinde veya yüksek trafikli uygulamalarda, isteklerin nereye geldiğini takip etmek ve anlık kararlar almak gerekir. İşte burada Token Bucket ve Sliding Window gibi algoritmalar devreye girer. Her biri farklı avantaj ve sınırlılıklar sunar.

Token Bucket Algoritması: Esneklik ve Basitlik

Token Bucket algoritması, bir su kovası analojisine dayanır. Sabit bir hızla belirli sayıda "jeton" (token) bir kovaya eklenir. Her istek geldiğinde, bu jetonlardan bir tanesi tüketilir. Jeton kalmadığında istek reddedilir veya sıraya alınır.

Token Bucket'ın temel özellikleri:

  • Sabit kapasiteli depo (örneğin maksimum 100 token)
  • Belirli bir refill oranı (örneğin saniyede 10 token)
  • Ani trafikle başa çıkmada daha esnek davranış
  • Konfigürasyonu kolay ve sezgisel

Örneğin, uygulamanız saniyede 100 istek kapasitesine sahip bir API'ye erişiyorsa, Token Bucket size şu senaryoya izin verir: Başlamada 100 tokeniniz var, her saniye 100 yeni token eklenir. Ani 150 isteği "biriktirmiş" tokenlerle (burst traffic) işleyebilirsiniz, ancak uzun vadede dakika başına maksimum 6.000 istek sınırında kalırsınız.

Token Bucket, başlangıç seviyesi API'ler ve küçölçekli uygulamalar için ideal seçimdir. Ancak dağıtık sistemlerde, tüm sunuculardaki token sayısını senkronize etmek zorlayıcı olabilir.

Sliding Window: Kesin ve Öngörülebilir

Sliding Window (kayan pencere) algoritması, zaman eksenini sabit aralıklara böler. Belirli bir pencere içinde kaç istek yapıldığını sayar. Pencere hareket ettikçe, eski istekler hesaptan çıkar.

Sliding Window'un temel özellikleri:

  • Sabit zaman pencereleri (örneğin 1 dakika)
  • Her istek için kesin bir zaman kaydı tutulur
  • Ani trafikle ilgili konularda daha katı davranış
  • Daha yüksek bellek tüketimi (tüm istekleri kaydetmek gerekir)

Sliding Window, kesinliği tercih eden senaryolarda tercih edilir. Örneğin, bir ödeme API'si dakikada maksimum 60 işlem ruhsatı veriyorsa, Sliding Window bunu sıkı şekilde uygular. 00:00-00:59 arasında 60 işlem yapabilirsiniz, ama 00:55'te gelen istek sıfırlanmaz; pencere 01:00'da sıfırlanır.

Dezavantajları da vardır: Pencere sınırlarında (örneğin 00:59 ile 01:00 arasında) anomali yaşanabilir. İki saniye içinde 120 istek yapılabilir (60 + 60), bu da tasarımcıların istediği değildir.

Redis ile Dağıtık Rate Limiting

Tek bir makinada çalışan uygulamalar basit veri yapıları kullanabilir, ancak yükü birden fazla sunucu paylaşıyorsa, durumu ortak bir yerde tutmak gerekir. Redis, in-memory veri tabanıyla bu sorunu çözer.

Redis'te rate limiting uygulamak için iki yaklaşım yaygındır:

  • Token Bucket + Redis: Başarılı istekler sırasında token sayısı azaltılır. TTL (Time To Live) ayarıyla otomatik sıfırlama sağlanır.
  • Sliding Window + Redis: Tüm istek zaman damgaları bir sıralı set içinde tutulur. Pencerenin dışındaki veriler temizlenir.

Redis'in INCR, EXPIRE ve ZRANGE gibi komutları rate limiting için yeterince verimlidir. Ancak tüm merkezi sistemler gibi, Redis bizzat bir darboğaz haline gelebilir. Yüksek hacimli uygulamalar genellikle yerel rate limiter (her sunucuda) ve global rate limiter (merkezi) kombinasyon kullanır.

Kullanıcı Tabanlı vs IP Tabanlı Limitler

Rate limiting'in uygulanacağı seviye de tasarım kararıdır:

Ölçüt IP Tabanlı Kullanıcı Tabanlı
Kimlik Belirtme Kaynağın IP adresi Giriş yapmış kullanıcının ID'si
Güvenlik Saldırıların başladığı kaynağı engeller Kötü niyetli hesapları engeller
Esneklik Sorunu Kurumsal ağlardaki haklı kullanıcıları etkiler VPN'de birden fazla kullanıcı ayrı limitlenir
Uygun Kullanım Halka açık API'ler, ön kimlik doğrulama Giriş gerektiren hizmetler, premium katmanları

Çoğu modern uygulamada her iki seviyeyi birleştirmek ideal çözümdür: Anonim kullanıcılara IP bazında limit uygulanırken, giriş yapmış kullanıcılara daha cömert kullanıcı tabanlı limitler tanınabilir.

Sonuç: Hangi Algoritmayı Seçmeli?

Token Bucket ve Sliding Window arasında tercih, uygulamanızın gereksinimlerine bağlıdır. Ani trafiği absorbe etmek ve esnek olmak istiyorsanız Token Bucket tercih edin. Katı kontrol ve öngörülebilir davranış gerekiyorsa Sliding Window seçin. Dağıtık mimaride Redis'i entegre edin ve ölçeğinizi arttıkça yerel ve global limitler kombinasyonu kullanın. Kullanıcı ve IP tabanlı limitlerden en az birini mutlaka implemente edin—hangisini seçeceğiniz, uygulamanızın açıklığı ve doğrulanmış kullanıcı tabanının boyutuna göre değişir.