2008-08-29 37 views
194

Chúng tôi đang thử nghiệm với nhiều cách khác nhau để hành động sử dụng van tiết lưu trong một khoảng thời gian cho:Cách tốt nhất để thực hiện yêu cầu điều chỉnh trong ASP.NET MVC là gì?

  • Giới hạn câu hỏi/trả lời bài viết
  • Hạn chế chỉnh sửa
  • năng tìm lại thức ăn Hạn chế

Đối hiện tại, chúng tôi đang sử dụng Cache để chỉ cần chèn bản ghi hoạt động của người dùng - nếu bản ghi đó tồn tại nếu/khi người dùng thực hiện cùng một hoạt động, chúng tôi sẽ điều tiết.

Sử dụng bộ nhớ cache sẽ tự động cung cấp cho chúng tôi dữ liệu cũ và cửa sổ hoạt động trượt của người dùng, nhưng cách quy mô sẽ có thể là vấn đề.

Một số cách khác để đảm bảo rằng yêu cầu/hành động của người dùng có thể được điều chỉnh hiệu quả (nhấn mạnh vào sự ổn định) là gì?

+0

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. –

+1

Đó 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. –

Trả lời

217

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 :)

+4

câu hỏi nhanh - bạn đang sử dụng giá trị c.HttpContext.Request.UserHostAddress như một phần của khóa. Giá trị đó có thể rỗng hoặc không hoặc tất cả cùng một giá trị? (ví dụ, nếu bạn đang sử dụng một cân bằng tải và nó là IP của máy đó .. không phải là khách hàng thực) Giống như, làm của proxy hoặc cân bằng tải (tức là một BIG IP F5) đặt cùng một dữ liệu trong đó và bạn cần phải kiểm tra cho X-Forwarded-For also hay gì đó? –

+6

@ Pure.Krome - vâng, có thể. Khi truy xuất IP của máy khách, chúng tôi sử dụng một hàm trợ giúp kiểm tra cả các biến máy chủ 'REMOTE_ADDR' và' HTTP_X_FORWARDED_FOR' và khử trùng một cách thích hợp. –

+2

Nhưng điều này sẽ không hoạt động trong một trang trại sẽ không? Cho rằng làm thế nào nó có thể làm việc với Stack Overflow? Bạn không cần một số loại bộ nhớ cache được chia sẻ như với Windows Server AppFabric hoặc memcached? – BrettRobi

9

Chúng tôi sử dụng kỹ thuật được mượn từ URL này http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, không phải để điều chỉnh, nhưng đối với Dịch vụ từ chối của người nghèo (D.O.S). Đây cũng là dựa trên bộ nhớ cache và có thể tương tự như những gì bạn đang làm. Bạn đang điều chỉnh để ngăn chặn D.O.S. tấn công? Router chắc chắn có thể được sử dụng để giảm D.O.S; Bạn có nghĩ rằng một bộ định tuyến có thể xử lý các điều chỉnh bạn cần?

+1

Đó là khá nhiều những gì chúng tôi đã làm - nhưng nó làm việc tuyệt vời :) –

67

Microsoft có một phần mở rộng mới cho IIS 7 được gọi là Mở rộng hạn chế IP động cho IIS 7.0 - Beta.

"Hạn chế IP động cho IIS 7.0 là mô-đun cung cấp bảo vệ chống lại sự từ chối dịch vụ và các cuộc tấn công bạo lực trên máy chủ web và các trang web. số lượng yêu cầu đồng thời cao hoặc số lượng lớn yêu cầu trong một khoảng thời gian nhỏ bất thường. " http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

Ví dụ:

Nếu bạn đặt tiêu chí để chặn sau X requests in Y milliseconds hay X concurrent connections in Y milliseconds địa chỉ IP sẽ bị chặn cho Y milliseconds sau đó yêu cầu sẽ được phép trở lại.

+1

Bạn có biết nếu nó gây ra bất kỳ vấn đề với trình thu thập dữ liệu như Googlebot? – Helephant

+0

@Helephant http://webmasters.stackexchange.com/questions/26553/iis-dynamic-ip-restrictions-module-and-googlebot – Adrian

+1

Nó hiện đã được phát hành và đi kèm với IIS như phiên bản 8 - http: //www.iis .net/learn/get-start/whats-new-in-iis-8/iis-80-dynamic-ip-address-restricted –

Các vấn đề liên quan