Dưới đây là một phiên bản chung của những gì chúng ta đã sử dụng trên Stack Overflow trong năm qua: sử dụng
/// <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;
}
}
}
mẫu:
[Throttle(Name="TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)]
public ActionResult TestThrottle()
{
return Content("TestThrottle executed");
}
Các ASP.NET Cache hoạt động như một nhà vô địch ở đây - bằng cách sử dụng nó, bạn sẽ tự động làm sạch các mục nhập ga của bạn. Và với lưu lượng ngày càng tăng của chúng tôi, chúng tôi không thấy rằng đây là sự cố trên máy chủ.
Hãy phản hồi về phương pháp này; khi chúng tôi làm cho Stack Overflow tốt hơn, bạn sẽ nhận được Ewok fix thậm chí nhanh hơn :)
Nguồn
2009-08-23 08:21:56
Bạn đang cố gắng giới hạn cho mỗi người dùng hoặc cho mỗi câu hỏi? Nếu mỗi người dùng, có thể sử dụng phiên, đó sẽ là một tập hợp nhỏ hơn. –
Đó là mỗi người dùng, nhưng chúng tôi không thể sử dụng Phiên vì yêu cầu cookie - chúng tôi đang hạn chế dựa trên địa chỉ IP hiện tại. –