在ASP.NET中实现MVC请求限制的最佳方式? [英] Best way to implement request throttling in ASP.NET MVC?

查看:199
本文介绍了在ASP.NET中实现MVC请求限制的最佳方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在与不同的方法来节流用户操作实验中的定时间段内

We're experimenting with various ways to throttle user actions in a given time period:


  • 限制问题/答案的帖子

  • 限制编辑

  • 限制饲料检索

有关目前,我们正在使用高速缓存只需插入用户活动的记录 - 如果记录存在,如果/当用户执行相同的活动,我们油门

For the time being, we're using the Cache to simply insert a record of user activity - if that record exists if/when the user does the same activity, we throttle.

使用Cache自动给我们陈旧数据清理和滑动用户的活动窗口,但它是如何将规模可能是一个问题。

Using the Cache automatically gives us stale data cleaning and sliding activity windows of users, but how it will scale could be a problem.

什么是确保其他一些方法的请求/用户操作,可以有效节流(强调稳定性)?

What are some other ways of ensuring that requests/user actions can be effectively throttled (emphasis on stability)?

推荐答案

下面是我们一直在使用的堆栈溢出过去一年什么的一个仿制版本:

Here's a generic version of what we've been using on Stack Overflow for the past year:

/// <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缓存就像这里的冠军 - 通过使用它,你就会得到你的油门输入的自动清理。并与我们不断增长的流量,我们没有看到,这是在服务器上的问题。

The ASP.NET Cache works like a champ here - by using it, you get automatic clean-up of your throttle entries. And with our growing traffic, we're not seeing that this is an issue on the server.

随意给这种方法的反馈;当我们堆栈溢出更好,你让你的伊渥克修复更快:)

Feel free to give feedback on this method; when we make Stack Overflow better, you get your Ewok fix even faster :)

这篇关于在ASP.NET中实现MVC请求限制的最佳方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆