Nasıl benim sitenin API kullanıcıların boğacak mı?

5 Cevap php

Sitemde meşru kullanıcılar bazen istenmeyen sonuçlara neden API istekleri ile sunucu çekiç. Ben bir API (henüz kesin sınırı çözemedim) her 5 saniyede bir ya da n dakikada çağrıları aramak demek daha fazla bir limit enstitü istiyorum. Ben açıkçası DB her API çağrısı oturum ve onlar sınırı üzerinde iseniz görmek için her istek üzerine hesaplama yapmak, ama her istek üzerine tüm bu ekstra yükü amacı mağlup olacaktır olabilir. Ben bir sınırı enstitü kullanabilirsiniz diğer daha az kaynak-yoğun yöntemleri nelerdir? Ben buna değer ne için, PHP / Apache / Linux kullanıyorum.

5 Cevap

Tamam, orada any sunucuya yazar olmadan istedi ne yapmak için hiçbir şekilde, ama en azından her isteği oturum ortadan kaldırabilir. Tek yönlü ({[(2 süre için sadece son talep izler "sızıntılı kova" azaltma yöntemi ($last_api_request) ve istek / sınırı sayısının bir oran kullanılarak gereğidir )]}). Sızan kova (her saat sıfırlar Twitter API gaz aksine), sayacı sıfırlar asla, ama kova (kullanıcı sınırına ulaştı) dolarsa, onlar biraz boşaltmak için kova için n saniye beklemeniz gerekir başka bir istek yapmadan önce. Diğer bir deyişle, bir yuvarlanan limiti gibi önceki istekleri süre içinde varsa, onlar yavaş yavaş kova dışarı sızdırıyor; Eğer kova doldurmak eğer sadece kısıtlar.

Bu kod parçacığı her istek üzerine yeni bir $minute_throttle değerini hesaplamak olacaktır. Birden fazla hızlı bir şekilde kafa karıştırıcı yapmak için başlayacak rağmen .. vb, günlük, saatlik olarak herhangi bir süre için throttles ekleyebilirsiniz çünkü ben $minute_throttle olarak minute belirtilen kullanıcılar.

$minute = 60;
$minute_limit = 100; # users are limited to 100 requests/minute
$last_api_request = $this->get_last_api_request(); # get from the DB; in epoch seconds
$last_api_diff = time() - $last_api_request; # in seconds
$minute_throttle = $this->get_throttle_minute(); # get from the DB
if ( is_null( $minute_limit ) ) {
    $new_minute_throttle = 0;
} else {
    $new_minute_throttle = $minute_throttle - $last_api_diff;
    $new_minute_throttle = $new_minute_throttle < 0 ? 0 : $new_minute_throttle;
    $new_minute_throttle +=	$minute / $minute_limit;
    $minute_hits_remaining = floor( ( $minute - $new_minute_throttle ) * $minute_limit / $minute  );
    # can output this value with the request if desired:
    $minute_hits_remaining = $minute_hits_remaining >= 0 ? $minute_hits_remaining : 0;
}

if ( $new_minute_throttle > $minute ) {
    $wait = ceil( $new_minute_throttle - $minute );
    usleep( 250000 );
    throw new My_Exception ( 'The one-minute API limit of ' . $minute_limit 
    	. ' requests has been exceeded. Please wait ' . $wait . ' seconds before attempting again.' )
    );
}
# Save the values back to the database.
$this->save_last_api_request( time() );
$this->save_throttle_minute( $new_minute_throttle );

Siz "HER istek üzerine tüm thos ekstra havai amacı mağlup olacağını" söylüyorlar, ama ben bunun doğru olduğundan emin değilim. Sunucunuzun çarpmasını önlemek için amaç değil midir? Gerçekten sadece bir hızlı okuma / yazma gerektirir Bu, muhtemelen bunu uygulamak yoludur. Eğer performansı hakkında endişeli olsaydı bile, farklı bir DB / diske API sunucu kontrolleri çiftlik olabilir.

Eğer alternatifler istiyorsanız Ancak, sen kontrol mod_cband, bant genişliği daraltma yardımcı olmak için tasarlanmış bir üçüncü taraf apache modülü. Gerekir Öncelikle bant genişliği sınırlama için olmasına rağmen, o da istekleri saniyede dayalı Throttle edebilirsiniz. Ben hiç kullanmadım, bu yüzden almak istiyorum ne tür sonuçlar emin değilim. Orada da mod-gaz kelebeği adı verilen başka bir modül oldu, ama bu proje, artık kapalı görünüyor, ve Apache 1.3 serisi üzerinde herhangi bir şey için asla piyasaya sürülmedi.

Sıfırdan uygulamaya ek olarak ayrıca API altyapısı bir göz atabilirsiniz 3scale gibi (http://www.3scale.net) hangi yapar hızı sınırlayıcı yanı sıra diğer şeyler bir demet (analitik vb.) Orada bunun için bir PHP eklentisi bulunuyor: https://github.com/3scale/3scale_ws_api_for_php.

Ayrıca API Vernik Infront gibi bir şey sopa ve bunun gibi sınırlayıcı API oranını yapabilirsiniz.

Konuyu hala hayatta olup olmadığını bilmiyorum ama ben memcached gibi önbellekte bu istatistikleri tutmak için öneririm. Bu DB isteği oturum yükünü azaltmak ancak yine de amaca hizmet edecektir.

Basit çözüm, sadece sabit, zaman her API tuşunu 24 saatte istekleri sınırlı sayıda verin, ve bilinen bazı bunları sıfırlamak olacaktır.

Onların API isteklerini (sayaç yani size güveniyoruz yönüne bağlı olarak, sıfır veya sınıra ulaşırsa) tüketebileceği, onların sayacını sıfırlamak kadar onlara verileri sunan durdurmak.

Bu şekilde, bu istekleri ile çekiç değil their yararına olacaktır.