Frage

Wir experimentieren mit verschiedenen Möglichkeiten, Benutzeraktionen zu drosseln gegebenen Zeitraum:

  • Begrenzen Sie Frage-/Antwortbeiträge
  • Beschränken Sie die Bearbeitungen
  • Beschränken Sie Feedabrufe

Derzeit verwenden wir den Cache, um einfach einen Datensatz der Benutzeraktivität einzufügen. Wenn dieser Datensatz vorhanden ist und der Benutzer dieselbe Aktivität ausführt, drosseln wir ihn.

Die Verwendung des Cache führt automatisch zu veralteten Datenbereinigungen und gleitenden Aktivitätsfenstern der Benutzer, aber die Skalierung könnte ein Problem sein.

Welche anderen Möglichkeiten gibt es, um sicherzustellen, dass Anfragen/Benutzeraktionen effektiv gedrosselt werden können (Schwerpunkt auf Stabilität)?

War es hilfreich?

Lösung

Hier ist eine generische Version dessen, was wir im letzten Jahr auf Stack Overflow verwendet haben:

/// <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;
        }
    }
}

Beispielverwendung:

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

Der ASP.NET-Cache funktioniert hier hervorragend – wenn Sie ihn verwenden, erhalten Sie eine automatische Bereinigung Ihrer Drosseleinträge.Und angesichts unseres wachsenden Datenverkehrs sehen wir kein Problem auf dem Server.

Geben Sie gerne Feedback zu dieser Methode.Wenn wir Stack Overflow verbessern, bekommen Sie Ihr Ewok-Fix noch schneller :)

Andere Tipps

Microsoft hat eine neue Erweiterung für IIS 7 namens Dynamic IP Restrictions Extension for IIS 7.0 – Beta.

„Dynamic IP Restrictions for IIS 7.0 ist ein Modul, das Schutz vor Denial-of-Service- und Brute-Force-Angriffen auf Webserver und Websites bietet.“Dieser Schutz wird durch die vorübergehende Blockierung der IP-Adressen von HTTP-Clients gewährleistet, die ungewöhnlich viele gleichzeitige Anfragen stellen oder über einen kurzen Zeitraum eine große Zahl von Anfragen stellen.“ http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

Beispiel:

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

Wir verwenden die von dieser URL übernommene Technik http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, nicht wegen Drosselung, sondern wegen Denial Of Service (D.O.S.) eines armen Mannes.Dies ist ebenfalls Cache-basiert und ähnelt möglicherweise dem, was Sie gerade tun.Drosseln Sie, um D.O.S. zu verhindern?Anschläge?Router können durchaus zur Reduzierung von D.O.S. eingesetzt werden;Glauben Sie, dass ein Router die von Ihnen benötigte Drosselung bewältigen könnte?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top