Лучший способ реализовать регулирование запросов в ASP.NET MVC? - PullRequest
204 голосов
/ 29 августа 2008

Мы экспериментируем с различными способами регулирования действий пользователя за данный период времени :

  • Лимит вопросов / ответов на сообщения
  • Ограничение правок
  • Ограничение поиска каналов

В настоящее время мы используем кэш для простой вставки записи активности пользователя - если эта запись существует, если / когда пользователь выполняет ту же самую деятельность, мы ограничиваем ее.

Использование кэша автоматически дает нам устаревшую очистку данных и скользящие окна активности пользователей, но проблема масштабирования может быть проблемой.

Каковы другие способы обеспечения эффективного регулирования запросов / действий пользователя (акцент на стабильность)?

Ответы [ 3 ]

231 голосов
/ 23 августа 2009

Вот общая версия того, что мы использовали в переполнении стека в прошлом году:

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

Пример использования:

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

ASP.NET Cache здесь работает как первоклассный - используя его, вы получаете автоматическую очистку ваших записей газа. И с нашим растущим трафиком мы не видим, что это проблема на сервере.

Не стесняйтесь оставлять отзывы об этом методе; когда мы сделаем Stack Overflow лучше, вы получите Ewok fix еще быстрее:)

67 голосов
/ 25 февраля 2009

У Microsoft есть новое расширение для IIS 7, которое называется «Динамическое расширение ограничений IP для IIS 7.0 - бета-версия».

«Динамические ограничения IP для IIS 7.0» - это модуль, который обеспечивает защиту от атак типа «отказ в обслуживании» и атак методом «грубой силы» на веб-сервер и веб-сайты. Такая защита обеспечивается путем временной блокировки IP-адресов клиентов HTTP, которые делают необычно большое число одновременных запросов или которые делают большое количество запросов в течение небольшого периода времени. " http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

Пример:

Если вы установите критерии для блокировки после X requests in Y milliseconds или X concurrent connections in Y milliseconds, то IP-адрес будет заблокирован для Y milliseconds, тогда запросы будут снова разрешены.

10 голосов
/ 14 ноября 2008

Мы используем технику, заимствованную из этого URL http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, не для регулирования, а для отказа в обслуживании бедного человека (D.O.S). Это также основано на кеше и может быть похоже на то, что вы делаете. Вы душите, чтобы предотвратить D.O.S. атаки? Маршрутизаторы, безусловно, могут быть использованы для уменьшения D.O.S; Как вы думаете, маршрутизатор может справиться с регулированием, которое вам нужно?

...