我們在定的時間段用各種方式油門用戶操作實驗:在ASP.NET MVC中實現請求限制的最佳方法?
- 極限提問/回答的帖子
- 限制編輯
- 限制飼料檢索
對於目前,我們使用緩存來簡單地插入用戶活動記錄 - 如果該記錄存在/當用戶執行相同的活動時,我們就進行調節。
使用Cache會自動爲我們提供了陳舊的數據清洗和用戶的滑動活動窗口,但如何將規模可能是一個問題。
確保請求/用戶操作可以被有效抑制(強調穩定性)的其他方法是什麼?
我們在定的時間段用各種方式油門用戶操作實驗:在ASP.NET MVC中實現請求限制的最佳方法?
對於目前,我們使用緩存來簡單地插入用戶活動記錄 - 如果該記錄存在/當用戶執行相同的活動時,我們就進行調節。
使用Cache會自動爲我們提供了陳舊的數據清洗和用戶的滑動活動窗口,但如何將規模可能是一個問題。
確保請求/用戶操作可以被有效抑制(強調穩定性)的其他方法是什麼?
下面是我們一直在使用的堆棧溢出過去一年什麼的通用版本:
/// <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緩存就像一個冠軍在這裏 - 通過使用它,您可以自動清理油門條目。隨着我們日益增長的流量,我們沒有看到這是服務器上的問題。
隨時就此方法提供反饋;當我們使Stack Overflow更好時,您可以更快地獲得Ewok fix :)
我們使用這個網址http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx借來的技術,不是爲了限制,但對於一個窮人的拒絕服務(D.O.S)。這也是基於緩存的,可能與您正在做的相似。你是否在阻止D.O.S.節流?攻擊?路由器當然可以用來減少D.O.S;你認爲路由器可以處理你需要的節流嗎?
這幾乎是我們已經在做的 - 但它的工作效果很好:) – 2009-01-11 05:45:16
Microsoft對IIS 7新增了一個名爲動態IP限制擴展的擴展,用於IIS 7.0 - Beta。
「爲IIS 7.0的動態IP限制是提供針對Web服務器和Web站點上的服務和強力攻擊拒絕保護模塊。這種保護是由HTTP客戶誰做的暫時封鎖IP地址提供異常大量的併發請求或者在很短的時間內發出大量請求。「 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
然後請求將被再次允許之後。
您是否知道它是否會導致像Googlebot這樣的抓取工具出現問題? – Helephant 2013-08-23 13:17:18
您是想限制每個用戶還是每個問題?如果每個用戶,可以使用會話,這將是一個較小的集合。 – 2008-11-02 01:23:53
這是每個用戶,但我們無法使用會話,因爲這需要cookie - 我們目前正在基於IP地址進行限制。 – 2008-11-13 02:20:59