2010-01-29 36 views
8

Giả sử, về mặt lý thuyết, tôi có một hành động trang/bộ điều khiển trong trang web của mình thực hiện một số nội dung rất nặng. Mất khoảng 10 giây để hoàn thành hoạt động của nó.ASP.NET (MVC) Outputcache và yêu cầu đồng thời

Bây giờ, tôi sử dụng cơ chế outputcache của .NET để lưu trong 15 phút (để kiểm tra, tôi sử dụng [OutputCache(Duration = 900)]) Điều gì sẽ xảy ra nếu sau 15 phút, bộ nhớ cache đã hết hạn và 100 người dùng yêu cầu trang lại trong vòng 10 giây đó phải làm gì để xử lý nặng?

  1. Những thứ nặng được thực hiện chỉ lần đầu tiên, và có một số cơ chế khóa để các 99 người dùng khác sẽ nhận được kết quả bộ nhớ cache
  2. Những thứ nặng được thực hiện 100 lần (và máy chủ được tê liệt như có thể mất tối đa 100 * 10 giây)

Câu hỏi dễ có thể, nhưng tôi không chắc chắn 100%. Tôi hy vọng nó là số một, mặc dù :-)

Cảm ơn!

Trả lời

4

Vâng, nó phụ thuộc vào cách bạn đã cấu hình IIS. Nếu bạn có ít hơn 100 chủ đề công nhân (giả sử, 50), thì "công cụ nặng" được thực hiện 50 lần, làm tê liệt máy chủ của bạn và sau đó 50 yêu cầu còn lại sẽ được phân phát từ bộ nhớ cache.

Nhưng không, không có "cơ chế khóa" trên kết quả hành động được lưu trong bộ nhớ cache; điều đó sẽ phản tác dụng, phần lớn.

Chỉnh sửa: Tôi tin điều này là đúng, nhưng các bài kiểm tra của Nick nói cách khác và tôi không có thời gian để kiểm tra ngay bây giờ. Hãy tự mình thử! Phần còn lại của câu trả lời là không phụ thuộc vào ở trên, mặc dù, và tôi nghĩ rằng đó là quan trọng hơn.

Nói chung, tuy nhiên, không yêu cầu web, được lưu trong bộ nhớ cache hoặc cách khác, sẽ mất 10 giây để trả lại. Nếu tôi ở trong đôi giày của bạn, tôi sẽ xem xét bằng cách nào đó tính toán trước phần cứng của yêu cầu. Bạn vẫn có thể cache kết quả hành động nếu bạn muốn cache HTML, nhưng có vẻ như vấn đề của bạn hơi lớn hơn.

Bạn có thể cũng muốn consider asynchronous controllers. Cuối cùng, lưu ý rằng mặc dù IIS và ASP.NET MVC sẽ không khóa tính toán nặng này, bạn có thể. Nếu bạn sử dụng bộ điều khiển không đồng bộ kết hợp với một khóa trên tính toán, thì bạn sẽ có được hiệu quả hành vi mà bạn đang yêu cầu. Tôi thực sự không thể nói nếu đó là giải pháp tốt nhất mà không biết nhiều hơn về những gì bạn đang làm.

+0

Cảm ơn trời Tôi thực sự không có yêu cầu mất 10 giây, nhưng tôi phóng đại rất nhiều để minh họa một điểm. Tôi chỉ tò mò điều gì sẽ xảy ra trong một kịch bản như vậy. Cảm ơn! Có thể xem xét việc thực hiện các bộ điều khiển async mặc dù. – Razzie

+0

đã được một thời gian ... chỉ cần làm một bài kiểm tra bản thân mình mặc dù và tôi chắc chắn nó không khóa, như bạn nói. Cảm ơn. – Razzie

3

Dường như với khóa ở đây, làm một thử nghiệm đơn giản:

<%@ OutputCache Duration="10" VaryByParam="*" %> 

protected void Page_Load(object sender, EventArgs e) 
{ 
    System.Threading.Thread.Sleep(new Random().Next(1000, 30000)); 
} 

Trang đầu tiên chạm một breakpoint ở đó, mặc dù nó còn lại ngủ ... không có yêu cầu khác chạm một breakpoint trong phương thức Page_Load. ..nó đợi cho người đầu tiên hoàn thành và trả lại kết quả đó cho tất cả những người đã yêu cầu trang đó.

Lưu ý: điều này đơn giản hơn để thử nghiệm trong một kịch bản biểu mẫu web, nhưng vì đây là khía cạnh được chia sẻ của các khung công tác, bạn có thể thực hiện cùng một thử nghiệm trong MVC với cùng một kết quả.

Dưới đây là một cách khác để kiểm tra:

<asp:Literal ID="litCount" runat="server" /> 

public static int Count = 0; 

protected void Page_Load(object sender, EventArgs e) 
{ 
    litCount.Text = Count++.ToString(); 
    System.Threading.Thread.Sleep(10000); 
} 

Tất cả các trang xếp hàng trong khi yêu cầu đầu tiên đi ngủ sẽ có đầu ra đếm tương tự.

+0

Bạn đang thử nghiệm trên WebDev? Nó hoạt động * rất * khác với IIS trên một máy chủ đa lõi. –

+0

@Craig: Thử nghiệm sử dụng IIS 7.5, Windows 7 x64 trên quad-core –

+0

Điều đó có vẻ lạ. Có lẽ bạn đang sử dụng chế độ gỡ lỗi? Điều này thực sự * không nên * khóa. Các yêu cầu khác sẽ bị thiếu bộ nhớ cache. –

1

Tôi đã thực hiện một thử nghiệm nhỏ có thể hữu ích. Tôi tin rằng những gì tôi đã phát hiện ra là các yêu cầu uncached không chặn, và mỗi yêu cầu đến trong khi bộ nhớ cache đã hết hạn và trước khi nhiệm vụ được hoàn thành thì kích hoạt tác vụ đó.

Ví dụ: mã bên dưới mất khoảng 6-9 giây trên hệ thống của tôi bằng cách sử dụng Cassini. Nếu bạn gửi hai yêu cầu, cách nhau khoảng 2 giây (tức là hai tab trình duyệt), cả hai sẽ nhận được kết quả duy nhất. Yêu cầu cuối cùng để hoàn thành cũng là phản hồi được lưu trong bộ nhớ cache cho các yêu cầu tiếp theo.

// CachedController.cs 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 

namespace HttpCacheTest.Controllers 
{ 
    public class CachedController : Controller 
    { 
     // 
     // GET: /Cached/ 

     [OutputCache(Duration=20, VaryByParam="*")] 
     public ActionResult Index() 
     { 
      var start = DateTime.Now; 

      var i = Int32.MaxValue; 
      while (i > 0) 
      { 
       i--; 
      } 
      var end = DateTime.Now; 

      return Content(end.Subtract(start).ToString()); 
     } 

    } 
} 
3

Câu hỏi cũ, nhưng tôi đã gặp phải vấn đề này và đã thực hiện một số điều tra.

Ví dụ mã:

public static int Count; 
[OutputCache(Duration = 20, VaryByParam = "*")] 
public ActionResult Test() 
{ 
    var i = Int32.MaxValue; 
    System.Threading.Thread.Sleep(4000); 
    return Content(Count++); 
} 

Run nó trong một trình duyệt, và có vẻ như để khóa và chờ đợi.

Chạy trong các trình duyệt khác nhau (tôi đã thử nghiệm trong IE và firefox) và các yêu cầu không được giữ.

Vì vậy, hành vi "đúng" có nhiều việc phải làm với trình duyệt bạn đang sử dụng hơn là chức năng trong IIS.

Chỉnh sửa: Để làm rõ - Không khóa. Máy chủ bị ảnh hưởng bởi tất cả các yêu cầu quản lý để truy cập trước khi kết quả đầu tiên được lưu vào bộ nhớ cache, có thể dẫn đến một cú đánh mạnh trên máy chủ cho các yêu cầu nặng nề. (Hoặc nếu bạn gọi hệ thống bên ngoài, hệ thống đó có thể bị gỡ xuống nếu máy chủ của bạn phục vụ nhiều yêu cầu ...)

0

Bạn nên kiểm tra thông tin này here: "Bạn có một khách hàng duy nhất thực hiện nhiều yêu cầu đồng thời với máy chủ Hành vi mặc định là các yêu cầu này sẽ được tuần tự hóa; "

Vì vậy, nếu yêu cầu đồng thời từ máy khách đơn được tuần tự hóa, yêu cầu tiếp theo sẽ sử dụng bộ nhớ cache. Điều đó giải thích một số hành vi dường như trong một số câu trả lời ở trên (@ mats-nilsson và @ nick-craver)

Ngữ cảnh mà bạn đã cho chúng tôi thấy nhiều người dùng, sẽ đánh bạn cùng một lúc và máy chủ của bạn sẽ bận cho đến khi đã hoàn thành ít nhất một yêu cầu và tạo bộ nhớ cache đầu ra và sử dụng nó cho yêu cầu tiếp theo. Vì vậy, nếu bạn muốn tuần tự hóa nhiều người dùng yêu cầu cùng một tài nguyên, chúng tôi cần hiểu cách yêu cầu được tuần tự hóa hoạt động cho một người dùng. Đó là điều bạn muốn?

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