API'ye hız sınırı koymak: algoritma, anahtar ve yanıt tasarımı
API hız sınırlamada doğru algoritmayı seçmeyi, istemciyi tanımlamayı, 429 yanıtını ve başlıkları kurmayı Kong örneğiyle adım adım öğrenin.
Hız sınırı neden gerekir?
Bir API'yi herkese açtığınızda farklı türde yük gelir: iyi niyetli ama hatalı istemciler (sonsuz döngüde istek atan bir betik) ve kasıtlı kötüye kullanım (parola deneme, veri çekme, hizmet reddi). Hız sınırı, belirli bir zaman penceresinde bir istemcinin yapabileceği istek sayısını sınırlayarak her ikisinden de sistemi korur. Ayrıca ticari bir API için kullanım paketlerini (ücretsiz ve ücretli kademe) uygulamanın teknik mekanizmasıdır.
Hız sınırı tek başına güvenlik çözümü değildir. Dağıtık saldırıda saldırgan çok sayıda farklı adresten gelebilir; kimlik doğrulama, giriş denemesi kilitleme ve ağ düzeyindeki koruma ile birlikte düşünülmelidir. Sınırın asıl işi, adil kullanımı sağlamak ve arka uç kapasitesini korumaktır.
Algoritmayı seçmek
Yaygın yaklaşımların her birinin davranışı farklıdır.
- Sabit pencere (fixed window): Zaman dilimlere bölünür ve her dilimde sayaç sıfırlanır. Uygulaması en basittir. Zayıflığı, pencere sınırında ani patlamadır: bir pencerenin sonunda ve bir sonrakinin başında peş peşe istek atarak, kısa sürede normalin katını göndermek mümkündür.
- Kayan pencere (sliding window): Sayım, her isteğin zamanından geriye doğru bakılarak yapılır. Sınır etkisini giderir ama daha fazla bellek ve hesap ister.
- Jeton kovası (token bucket): Kovaya sabit hızla jeton eklenir, her istek bir jeton harcar. Kova doluysa kısa süreli patlamaya izin verir, uzun vadede ortalama hızı sınırlar. Çoğu genel API için iyi bir denge sunar.
- Sızan kova (leaky bucket): İstekler kuyruğa girer ve sabit hızla işlenir. Arka ucun düzgün hızda yük almasını istediğinizde uygundur.
Seçim sorusu şudur: kısa patlamaya izin vermek istiyor muyum? Evet ise jeton kovası, hayır ve akışın düzgün olması gerekiyorsa sızan kova; basitlik ön plandaysa sabit pencere.
Sınırı kime uygulayacaksınız?
Sınırın anahtarı, kimin sayılacağıdır. Seçenekler:
- İstemci IP adresi: kimlik doğrulama öncesi uç noktalar için tek seçenektir ama ortak ağ çıkışı kullanan kurumsal kullanıcıları haksız yere sınırlayabilir.
- Kimliği doğrulanmış kullanıcı ya da tüketici: kimlik doğrulamadan sonraki uç noktalar için en adil anahtardır.
- API anahtarı ya da uygulama kimliği: ticari paketler için doğaldır.
- Uç nokta bazlı: giriş ya da parola sıfırlama gibi pahalı ve riskli işlemler için daha sıkı sınır; okuma uç noktaları için gevşek sınır.
Birden çok katmanı birleştirmek yaygındır: genel bir sınır ile pahalı uç noktalar için ayrı, daha sıkı bir sınır birlikte uygulanır. Sınırları ilk günden belirlerken tahmin yürütmek yerine gerçek trafik verisine bakın: normal bir istemci yoğun saatte ne kadar istek yapıyor? Sınırı bunun üstünde, ama sisteminizi korumaya yetecek kadar düşük koyun.
İstemciye ne söylemelisiniz?
Sınır aşıldığında standart yanıt, 'çok fazla istek' anlamına gelen 429 durum kodudur. Yanıtın yanında istemciye ne zaman yeniden deneyeceğini söylemek, onu körü körüne tekrar denemekten alıkoyar. Kong'un hız sınırlama eklentisinin belgesine göre aşıldığında 429 ve 'API rate limit exceeded' mesajlı bir gövde döner; yanıtlar ayrıca Retry-After başlığını taşır.
Başarılı yanıtlarda da kalan hakkı bildiren başlıklar göndermek, istemcinin kendi hızını ayarlamasına yardım eder. Kong'da RateLimit-Limit, RateLimit-Remaining ve RateLimit-Reset başlıkları ile zaman birimine göre X-RateLimit başlıkları bulunur; istemciden gizlemek isterseniz hide_client_headers seçeneği vardır.
İstemci tarafında üstel geri çekilme (exponential backoff) uygulayın: yeniden deneme aralığını her denemede artırın ve rastgele bir sapma ekleyin. Tüm istemciler aynı anda yeniden denerse, sınır kalkar kalkmaz yeni bir yük dalgası oluşur.
Kong ile uygulamak: örnek yapılandırma
API geçidi katmanında sınır koymak, her servise ayrı kod yazmaktan daha tutarlıdır. Kong'un hız sınırlama eklentisinde süre birimleri saniye, dakika, saat, gün, ay ve yıl olarak verilir. Depolama için policy alanı local, cluster ve redis değerlerini alır.
- local: sayaçlar her Kong düğümünün belleğinde tutulur. Hızlıdır, ama birden çok düğüm varsa toplam sınır düğüm sayısıyla çarpılmış gibi davranır.
- cluster: sayaçlar Kong'un kendi veri tabanında tutulur. Tutarlıdır ama her istekte veri tabanına gider.
- redis: sayaçlar harici bir Redis'te tutulur; çok düğümlü kurulumlarda doğru toplam sayım ve iyi performans için yaygın seçimdir. Redis bağlantı bilgileri (adres, port, kullanıcı adı) eklenti yapılandırmasında verilir.
Deklaratif yapılandırma dosyasında bir servise bağlı örnek şöyle olabilir:
plugins: - name: rate-limiting service: order-service config: minute: DAKIKALIK_ISTEK_SAYISI policy: redis redis: host: cache-server
Bu örnekteki dakikalık değer yalnızca bir örnektir; gerçek değeri trafik verinizle belirleyin. Sınırı tek tek tüketicilere bağlamak için eklentiyi tüketici kapsamında tanımlayın.
Test, izleme ve ayarlama
Sınırı devreye almadan önce davranışını test edin. Bir betikle sınırı aşan sayıda istek gönderin; ilk istekler başarılı olmalı, aşımdan sonra 429 dönmeli, bekleme süresi dolunca tekrar başarılı olmalıdır. Başlıkların değerlerini de kontrol edin.
Üretimde şunları izleyin: sınırlanan istek sayısı, hangi istemcilerin sınıra çarptığı ve uç nokta bazında dağılım. Meşru bir istemci sürekli sınıra çarpıyorsa, sınır çok sıkı ya da istemci verimsiz çalışıyor demektir; verimsiz istemci durumunda istemci geliştiricisine toplu çağrı ve önbellek önerin.
Depolama katmanı (örneğin Redis) çökerse ne olacağını önceden kararlaştırın. Sistem açık mı kalsın (sınırsız geçirsin) yoksa kapalı mı (hepsini reddetsin)? Çoğu genel API'de erişilebilirlik öncelikli olduğundan açık kalmayı seçer; güvenlik açısından kritik uç noktalarda ise reddetmek tercih edilebilir. Kararı yazılı hale getirin.
Sık yapılan hatalar
- Sınırı yalnızca IP'ye göre koymak. Ortak çıkış adresindeki kullanıcılar birbirini bloke eder.
- Tek bir genel sınır kullanıp pahalı uç noktaları korumasız bırakmak.
- Yanıtta bekleme bilgisi vermemek. İstemci hemen tekrar dener, yük artar.
- Çok düğümlü kurulumda yerel sayaç kullanıp gerçek sınırı yanlış hesaplamak.
- Sınırı veriye dayanmadan belirlemek. Çok gevşekse koruma yok, çok sıkıysa meşru kullanıcı cezalanır.
- Sınırı aşan istemciyi izlememek. Kötüye kullanım ya da hatalı istemci tespit edilemez.
- Sınırı yalnızca bir katmanda tutmak. Geçit ve uygulama düzeyinde birbirini tamamlayan sınırlar daha dayanıklıdır.
Bu beceriyi Mindset programlarında nerede çalışırsınız?
Kong ile API Gateway İşletimi programı, trafik yönetimi eklentileri ve gözlemlenebilirlik modülleriyle bu sayfadaki sınırlama ve izleme konularını doğrudan karşılıyor; platform ve DevOps ekipleri için uygun görünüyor. API'yi tasarlayan taraf için REST API En İyi Pratikler programındaki hata yönetimi, performans ve önbellekleme başlıkları, 429 yanıtının sözleşmeye nasıl oturacağı konusunu tamamlıyor.
Kurumsal ekiplerde ortak bir sınır politikası (hangi uç nokta, hangi anahtar, hangi yanıt biçimi) yazılı hale geldiğinde, farklı servisleri tüketen ekipler her servis için ayrı sürprizle karşılaşmaz.
İlgili Mindset programı
Kong ile API Gateway İşletimi
Sık sorulan sorular
429 yanıtında hangi başlıklar bulunmalı?
En azından Retry-After başlığı bulunmalı; istemciye ne zaman tekrar deneyeceğini söyler. Kalan hakkı ve sıfırlanma zamanını bildiren başlıklar da istemcinin kendi hızını ayarlamasına yardımcı olur. Gövdede kısa ve makine tarafından okunabilir bir hata bilgisi verin.
Hız sınırı ile kota arasındaki fark nedir?
Hız sınırı kısa zaman diliminde (saniye, dakika) isteğin yoğunluğunu kontrol eder ve sistemi korur. Kota ise daha uzun dönemde (gün, ay) toplam kullanım hakkını belirler ve genelde ticari paketlerle ilişkilidir. İkisi birlikte kullanılabilir.
Redis olmadan çok düğümlü kurulumda sınır uygulanabilir mi?
Uygulanabilir ama doğruluk düşer. Yerel sayaçlarda her düğüm kendi sayısını tutar; toplam sınır düğüm sayısı kadar katlanır. Yük dengeleyici aynı istemciyi hep aynı düğüme yönlendiriyorsa fark azalır. Kesin sınır gerekiyorsa ortak bir depolama kullanın.
Sınır değerini nasıl belirlerim?
Gerçek trafik verisine bakın: normal bir istemcinin yoğun saatteki isteğini ölçün ve arka ucun kaldırabileceği kapasiteyle karşılaştırın. Sınırı normal kullanımın rahatça üstünde, ama sistemi koruyacak kadar düşük koyun. Sonra ihlal verisini izleyerek ayarlayın.
İlgili rehberler
İlgili eğitimler
Kategori: Yazılım Geliştirme, DevOps ve Bulut Teknolojileri