2008-08-29 18 views
194

Wir mit verschiedenen Möglichkeiten, um Gasbenutzeraktionen in einem gegebenen Zeitraum experimentieren:Die beste Methode zum Implementieren der Anforderungsbeschränkung in ASP.NET MVC?

  • Grenze Frage/Antwort-Beiträge
  • Grenze bearbeitet
  • Limit-Feed Auslagerungen

Für Vorläufig verwenden wir den Cache, um einfach eine Aufzeichnung der Benutzeraktivität einzufügen. Wenn dieser Datensatz existiert, wenn der Benutzer die gleiche Aktivität ausführt, drohen wir.

Die Verwendung des Cache gibt uns automatisch abgestandene Datenreinigungs- und Schiebeaktivitätsfenster von Benutzern, aber wie es skalieren könnte ein Problem sein.

Mit welchen anderen Methoden können Sie sicherstellen, dass Anforderungen/Benutzeraktionen effektiv gedrosselt werden können (Schwerpunkt auf Stabilität)?

+0

Sie versuchen, pro Benutzer oder pro Frage zu begrenzen? Wenn pro Benutzer, könnte Sitzung verwendet werden, die eine kleinere Menge wäre. –

+1

Es ist pro Benutzer, aber wir konnten Session nicht verwenden, da dies Cookies erfordert - wir beschränken derzeit basierend auf IP-Adresse. –

Antwort

217

Hier ist eine generische Version von dem, was wir haben für das vergangene Jahr auf Stack-Überlauf wurde unter Verwendung von:

/// <summary> 
/// Decorates any MVC route that needs to have client requests limited by time. 
/// </summary> 
/// <remarks> 
/// Uses the current System.Web.Caching.Cache to store each client request to the decorated route. 
/// </remarks> 
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 
public class ThrottleAttribute : ActionFilterAttribute 
{ 
    /// <summary> 
    /// A unique name for this Throttle. 
    /// </summary> 
    /// <remarks> 
    /// We'll be inserting a Cache record based on this name and client IP, e.g. "Name-192.168.0.1" 
    /// </remarks> 
    public string Name { get; set; } 

    /// <summary> 
    /// The number of seconds clients must wait before executing this decorated route again. 
    /// </summary> 
    public int Seconds { get; set; } 

    /// <summary> 
    /// A text message that will be sent to the client upon throttling. You can include the token {n} to 
    /// show this.Seconds in the message, e.g. "Wait {n} seconds before trying again". 
    /// </summary> 
    public string Message { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext c) 
    { 
     var key = string.Concat(Name, "-", c.HttpContext.Request.UserHostAddress); 
     var allowExecute = false; 

     if (HttpRuntime.Cache[key] == null) 
     { 
      HttpRuntime.Cache.Add(key, 
       true, // is this the smallest data we can have? 
       null, // no dependencies 
       DateTime.Now.AddSeconds(Seconds), // absolute expiration 
       Cache.NoSlidingExpiration, 
       CacheItemPriority.Low, 
       null); // no callback 

      allowExecute = true; 
     } 

     if (!allowExecute) 
     { 
      if (String.IsNullOrEmpty(Message)) 
       Message = "You may only perform this action every {n} seconds."; 

      c.Result = new ContentResult { Content = Message.Replace("{n}", Seconds.ToString()) }; 
      // see 409 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 
      c.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict; 
     } 
    } 
} 

Verwendungsbeispiel:

[Throttle(Name="TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)] 
public ActionResult TestThrottle() 
{ 
    return Content("TestThrottle executed"); 
} 

Die ASP.NET-Cache hier wie ein Weltmeister arbeitet - Sie erhalten damit eine automatische Bereinigung Ihrer Gaseingänge. Und mit dem wachsenden Traffic sehen wir nicht, dass dies ein Problem auf dem Server ist.

Fühlen Sie sich frei, Feedback zu dieser Methode zu geben; Wenn wir Stack Overflow besser machen, bekommen Sie Ihre Ewok fix noch schneller :)

+4

schnelle Frage - Sie verwenden den Wert c.HttpContext.Request.UserHostAddress als Teil des Schlüssels. Ist dieser Wert möglich leer oder null oder der gleiche Wert? (Dh, wenn Sie einen Load Balancer verwenden und es ist die IP dieses Rechners .. nicht die echten Clients) Wie Proxy oder Load Balancer (dh ein BIG IP F5) setzen Sie die gleichen Daten dort und Sie müssen überprüfen für X-Forwarded-For auch oder sowas? –

+6

@ Pure.Krome - ja, könnte es sein. Beim Abrufen der Client-IP verwenden wir eine Hilfsfunktion, die sowohl die Servervariablen "REMOTE_ADDR" als auch "HTTP_X_FORWARDED_FOR" überprüft und entsprechend bereinigt. –

+2

Aber das würde nicht in einer Webfarm funktionieren, oder? Wie kann es mit Stack Overflow funktionieren? Benötigen Sie keine Art von gemeinsam genutztem Cache wie mit Windows Server AppFabric oder memcached? – BrettRobi

9

Wir verwenden die von dieser URL geliehene Technik http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, nicht zum Drosseln, aber für einen Denial Of Service (D.O.S) eines armen Mannes. Dies ist ebenfalls cachebasiert und ähnelt möglicherweise dem, was Sie gerade tun. Drosseln Sie, um D.O.S zu verhindern Anschläge? Router können sicherlich verwendet werden, um D.O.S zu reduzieren; Glaubst du, dass ein Router mit der benötigten Drosselung umgehen kann?

+1

Das ist ziemlich genau das, was wir bereits machen - aber es funktioniert großartig :) –

67

Microsoft hat eine neue Erweiterung für IIS 7 mit dem Namen Dynamic IP Restrictions Extension für IIS 7.0 - Beta.

„Die dynamische IP-Einschränkungen für IIS 7.0 ein Modul, das den Schutz vor Denial-of-Service und Brute-Force-Angriffe auf Web-Server und Web-Sites. Ein solcher Schutz bietet durch vorübergehend blockiert IP-Adressen der HTTP-Clients zur Verfügung gestellt, die machen ungewöhnlich hohe Anzahl von gleichzeitigen Anfragen oder die große Anzahl von Anfragen über einen kleinen Zeitraum. " http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

Beispiel:

Wenn Sie die Kriterien blockieren nach X requests in Y milliseconds oder X concurrent connections in Y milliseconds die IP-Adresse wird für die blockiert werden Y milliseconds dann Anfragen wieder zugelassen werden.

+1

Wissen Sie, ob es irgendwelche Probleme mit Crawlern wie dem Googlebot verursacht hat? – Helephant

+0

@Helephant http://webmasters.stackexchange.com/questions/26553/iis-dynamic-ip-restrictions-module-and-googlebot – Adrian

+1

Es ist jetzt veröffentlicht und gebündelt mit IIS ab Version 8 - http: //www.iis .net/learn/get-started/whats-new-in-iis-8/iis-80-dynamische-ip-adresse-restriktionen –

Verwandte Themen