Pregunta

Estamos experimentando con varias formas de limitar las acciones de los usuarios en un período de tiempo dado:

  • Limitar publicaciones de preguntas/respuestas
  • Limitar ediciones
  • Limitar las recuperaciones de feeds

Por el momento, estamos usando la caché para simplemente insertar un registro de la actividad del usuario; si ese registro existe, si/cuando el usuario realiza la misma actividad, lo limitamos.

El uso de la caché nos brinda automáticamente limpieza de datos obsoletos y ventanas deslizantes de actividad de los usuarios, pero cómo se escalará podría ser un problema.

¿Cuáles son algunas otras formas de garantizar que las solicitudes/acciones de los usuarios puedan limitarse de manera efectiva (énfasis en la estabilidad)?

¿Fue útil?

Solución

Aquí hay una versión genérica de lo que hemos estado usando en Stack Overflow durante el año pasado:

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

Uso de muestra:

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

El caché ASP.NET funciona como un campeón aquí: al usarlo, obtienes una limpieza automática de tus entradas de aceleración.Y con nuestro creciente tráfico, no vemos que esto sea un problema en el servidor.

No dude en dar su opinión sobre este método;Cuando mejoramos Stack Overflow, obtienes tu arreglo de ewok aun más rápido :)

Otros consejos

Microsoft tiene una nueva extensión para IIS 7 llamada Extensión de restricciones de IP dinámicas para IIS 7.0 - Beta.

"Las Restricciones Dinámicas de IP para IIS 7.0 es un módulo que brinda protección contra denegación de servicio y ataques de fuerza bruta en servidores y sitios web.Dicha protección se proporciona bloqueando temporalmente las direcciones IP de los clientes HTTP que realizan una cantidad inusualmente alta de solicitudes simultáneas o que realizan una gran cantidad de solicitudes durante un período de tiempo corto". http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

Ejemplo:

Si establece los criterios para bloquear después X requests in Y milliseconds o X concurrent connections in Y milliseconds la dirección IP será bloqueada por Y milliseconds entonces las solicitudes se permitirán nuevamente.

Usamos la técnica tomada de esta URL. http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, no por estrangulamiento, sino por la Denegación de Servicio (D.O.S) de un pobre.Esto también se basa en caché y puede ser similar a lo que estás haciendo.¿Está acelerando para evitar que D.O.S.ataques?Ciertamente se pueden utilizar enrutadores para reducir el D.O.S;¿Crees que un enrutador podría manejar la aceleración que necesitas?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top