asp.net-mvc 在 ASP.NET MVC 中实现请求限制的最佳方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to implement request throttling in ASP.NET MVC?
提问by Jarrod Dixon
We're experimenting with various ways to throttle user actions in a given time period:
我们正在尝试各种方法来限制给定时间段内的用户操作:
- Limit question/answer posts
- Limit edits
- Limit feed retrievals
- 限制问答帖
- 限制编辑
- 限制提要检索
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.
目前,我们使用缓存来简单地插入用户活动的记录——如果该记录存在,如果/当用户进行相同的活动时,我们就会进行节流。
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)?
还有哪些其他方法可以确保可以有效地限制请求/用户操作(强调稳定性)?
回答by Jarrod Dixon
Here's a generic version of what we've been using on Stack Overflow for the past year:
这是我们过去一年在 Stack Overflow 上使用的通用版本:
/// <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;
}
}
}
Sample usage:
示例用法:
[Throttle(Name="TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)]
public ActionResult TestThrottle()
{
return Content("TestThrottle executed");
}
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.
ASP.NET 缓存在这里就像一个冠军 - 通过使用它,您可以自动清理您的节流条目。随着我们不断增长的流量,我们没有看到这是服务器上的问题。
Feel free to give feedback on this method; when we make Stack Overflow better, you get your Ewok fixeven faster :)
请随时对此方法提供反馈;当我们让 Stack Overflow 变得更好时,您会更快地修复 Ewok:)
回答by notandy
Microsoft has a new extension for IIS 7 called Dynamic IP Restrictions Extension for IIS 7.0 - Beta.
Microsoft 有一个新的 IIS 7 扩展,称为 IIS 7.0 的动态 IP 限制扩展 - Beta。
"The Dynamic IP Restrictions for IIS 7.0 is a module that provides protection against denial of service and brute force attacks on web server and web sites. Such protection is provided by temporarily blocking IP addresses of the HTTP clients who make unusually high number of concurrent requests or who make large number of requests over small period of time." http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/
“IIS 7.0 的动态 IP 限制是一个模块,它提供针对 Web 服务器和网站的拒绝服务和蛮力攻击的保护。这种保护是通过临时阻止发出异常大量并发请求的 HTTP 客户端的 IP 地址来提供的或者在短时间内提出大量请求的人。” http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/
Example:
例子:
If you set the criteria to block after X requests in Y millisecondsor X concurrent connections in Y millisecondsthe IP address will be blocked for Y millisecondsthen requests will be permitted again.
如果您将条件设置为阻止X requests in Y milliseconds或X concurrent connections in Y millisecondsIP 地址将被阻止,Y milliseconds则将再次允许请求。
回答by Rob Kraft
We use the technique borrowed from this URL http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, not for throttling, but for a poor man's Denial Of Service (D.O.S). This is also cache-based, and may be similar to what you are doing. Are you throttling to prevent D.O.S. attacks? Routers can certainly be used to reduce D.O.S; do you think a router could handle the throttling you need?
我们使用从这个 URL http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx借来的技术,不是为了节流,而是为了穷人的拒绝服务 (DOS)。这也是基于缓存的,可能与您正在执行的操作类似。您是否正在限制以防止 DOS 攻击?路由器当然可以用来减少DOS;您认为路由器可以处理您需要的节流吗?

