API Throttling Nedir?

Melihkarakoc
Volt Lines
Published in
3 min readDec 16, 2021

Merhabalar :) Volt Lines’ta 2 yılı aşkın süredir Backend Developer pozisyonunda çalışmaktayım. Bu süre zarfında kullandığımız API’ların geliştirmesi ve bakımlarından sorumluyum diyebiliriz. Neden Throttling hakkında yazmayı tercih ettim? Çünkü bu konu hakkındaki kaynakların az olduğunu gördük. Aynı zamanda Throttling sayesinde az bir efor ile uygulamanızın performansını önemli ölçüde arttırabilir veya güvenliğini sağlayabilirsiniz.

Throttling Türkçeye ayarlama, daraltma, kısma vb. olarak çevriliyor. Throttling, istemcilerin (client) API’ya yapacağı istekleri ayarlamak için kullanılıyor. Örneğin; kısa zaman aralıklarında, tek bir istemciden, API’nıza anormal derecede yüksek istek alıyorsanız (bu durum uygulamanızın yavaş çalışmasına veya hiç cevap vermemesine sebep olabilir), bu istekleri Throttling ile özelleştirilmiş bir şekilde kısıtlayabilirsiniz.

Django “out of box” Konsepti

Django birçok kullanıma hazır (out of box) özellik ile birlikte gelir. Örneğin; admin paneli, ORM aracı, template engine vb. Django Rest Framework (DRF) altında bulunan Throttling de bize 3 adet ‘kullanıma hazır’ Throttle seçeneği sunar. Bunlar AnonRateThrottle, UserRateThrottle ve ScopedRateThrottle’dır. Bu yazımda ben AnonRateThrottle ve UserRateThrottle’ı açıklayacağım.

  1. AnonRateThrottle: Sadece anonim kullanıcıların isteklerini kısıtlamak için kullanılabilir (Örneğin; anonim kullanıcılarınıza günlük istek limiti koyarken, diğer kullanıcılarınıza bir sınır koymak istemediğimiz bir senaryoda kullanışlı olabilir).
  2. UserRateThrottle: Kullanıcı id ya da ip adresi (anonim kullanıcılar için) ile unique bir key oluşturur. Bu key ile kullanıcı/zaman bazlı kısıtlama yapmamıza imkan verir.

DRF Throttling, saniye/dakika/saat/gün tipinde periyotlarda konfigürasyon yapmamıza olanak sağlar. Bu konfigürasyonları django settings içine koyarak tüm API’nız için geçerli kılabilir veya size uygun Django Rate Throttle sınıflarından, özelleştirilmiş kendi throttle sınıfınızı oluşturabilirsiniz.

Belirlediğimiz limitler aşılınca, Throttling devreye girip “429 status code” ile ‘Too Many Requests’ hatası istemciye döner.

Yukarıdaki konfigürasyonlar ile API “uç noktaları”na (settings içine koyduğumuz için tüm API uç noktaları etkilenir) kimliği doğrulanmış istemciler için saatlik 1000 istek, anonim istemciler için günlük 100 istek kısıtlamaları koymuş oluruz.

Volt Lines olarak dayanıklı ve yüksek performanslı bir API yaratmak için aradığımız geliştirmelerden biri Throttling idi. Volt Lines’ta sürücü mobil uygulamamız var. Bu mobil uygulamanın idealde 5 saniyede bir lokasyon bilgileri için, API’mıza POST isteğinde bulunması gerekiyor. Ancak monitoring araçlarımızdan baktığımızda, tek bir kullanıcıdan beklenen sayıdan 5 katı daha fazla lokasyon bilgisi geldiğini fark ettik. Tam bu noktada Django Throttling kullanmaya karar verdik. Ancak 1 saniye veya 1 dakika bazlı bir kısıtlama bizim için kullanışlı değildi. 9 saniyede 5 istek veya 5 saniyede 1 istek gibi daha özelleştirilmiş bir konfigürasyona ihtiyacımız vardı.

Bunun için UserRateThrottle sınıfından kalıtım yapan, özelleştirilmiş bir Throttle sınıfı yazdık ve default “parse_rate” metodunu override ettik.

1–15. satırlar arasında konfigürasyon değerlerini görebilirsiniz. 3 saniyede sadece 1 isteğe cevap vermek istiyorsak, kind değeri second, request count değeri 1 ve kind_interval değeri ise 3 olmalıdır.

43. satırda rate konfigürasyon değerini parçalıyoruz ki, 45. satırda hangi hangi tip periyotta (saniye/dakika/saat/gün) olduğunu eşleştirip ona göre uygun saniye değeri ile çarpalım. Daha sonra bu eşleşmeden gelen değer ile interval değerini çarpınca bize “(1, 3)” değerinde bir tuple dönüyor. Bu da 3 saniyede 1 isteğe cevap vereceğimiz anlamına geliyor.

Daha sonrasında kullandığımız Django View yapısına liste içerisinde, özelleştirilmiş Throttle sınıfımızı tanımlayarak işlemi tamamlıyoruz.

Aşağıda 3 saniyede 4 isteğe izin veren Throttle ayarları ile test sonucunu görüyoruz. 12:37:35 saatine kadar test edilen kullanıcıdan gelen isteklerden sadece 4’üne “200 status code” ile cevap verildiğini, geriye kalanın “429 status code” ile reddedildiğini görüyoruz.

Son olarak monitoring araçlarınızdan bu hata kodunu loglamayı çıkarmayı düşününebilirsiniz çünkü aksi takdirde API’nızın hata yüzdesi çok yüksek çıkacaktır.

--

--