2010-01-29 3 views
8

이론적으로 웹 사이트에 매우 무거운 것을 수행하는 페이지/컨트롤러 작업이 있습니다. 작업을 완료하는 데 약 10 초가 걸립니다.ASP.NET (MVC) Outputcache 및 동시 요청

이제 .NET의 outputcache 메커니즘을 사용하여 15 분 동안 캐시합니다 (예 : [OutputCache(Duration = 900)]). 15 분 후에 캐시가 만료되고 100 명의 사용자가 10 초 이내에 다시 페이지를 요청하면 어떻게됩니까? 그것은 무거운 처리를 할 소요됩니까?

  1. 무거운 물건은 처음에만 수행하고 다른 99 사용자가 무거운 물건은 100 회 이루어집니다 (그리고 서버로 불구가되어
  2. 캐시 결과를 얻을 수 있도록 일부 잠금 메커니즘이 최대 100 * 10 초 소요될 수 있습니다.)

쉬운 질문 일 수도 있지만 100 % 확실하지 않습니다. 그래도 번호 1이 되길 바랍니다 .-)

고마워!

답변

4

글쎄, IIS 구성 방법에 따라 다릅니다. 50 개 미만의 작업자 스레드가있는 경우 "무거운 작업"이 50 번 수행되어 서버가 손상된 다음 나머지 50 개의 요청이 캐시에서 제공됩니다.

아니요, 아니요, 캐시 된 작업 결과에는 '잠금 메커니즘'이 없습니다. 그것은 대부분 비생산적입니다.

편집 : 나는 이것이 사실이라고 믿지만, Nick의 테스트는 그렇지 않다고 말하면서 지금 테스트 할 시간이 없습니다. 직접 체험 해보십시오! 나머지 대답은 위와는 관계가 없지만 더 중요하다고 생각합니다.

그러나 일반적으로 웹 요청은 캐시되거나 다른 방식으로 반환되기까지 10 초가 걸리지 않습니다. 제가 신발에 있다면, 어떻게 든 사전 요청의 어려운 부분을 살펴볼 것입니다. HTML을 캐시하고 싶다면 액션 결과를 캐시 할 수 있지만, 문제가 다소 크다.

고객 consider asynchronous controllers으로 변경하고 싶습니다. 마지막으로, IIS와 ASP.NET MVC가이 엄청난 계산을 잠그지는 않을지라도, 여러분은 그렇게 할 수 있습니다. 비동기 컨트롤러를 계산에 대한 잠금과 결합하면, 당신이 요구하는 행동을 효과적으로 얻을 수 있습니다. 네가하는 일에 대해 더 많이 알지 못해서 그것이 최선의 해결책이라면 나는 정말로 말할 수 없다.

+0

감사의 하늘 정말 10 초가 걸리는 요청이 없습니다. 그러나 요점을 설명하기 위해 크게 과장했습니다. 나는 그런 시나리오에서 일어날 일이 궁금했다. 감사! 하지만 비동기 컨트롤러 구현을 고려할 수도 있습니다. – Razzie

+0

잠시 동안 ... 나 자신을 시험해 봤지만 당신이 말한 것처럼 잠기지 않을 것이라고 확신합니다. 감사. – Razzie

3

간단한 테스트를하고, 여기에 잠글 것 같다

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

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

첫 번째 페이지가 다른 요구를 Page_Load 방법에 중단 점을 명중하지 ... 자고 남아에도 불구하고, 거기에 중단 점을 안타. 첫 번째 페이지가 완료 될 때까지 기다렸다가 그 페이지를 요청한 모든 사용자에게 그 결과를 반환합니다.

참고 : 이것은 웹 양식 시나리오에서 테스트하는 것이 더 간단했지만, 이는 프레임 워크의 공유 측면이므로 동일한 결과로 MVC에서 동일한 테스트를 수행 할 수 있습니다.

여기 시험에 대한 대안 방법 : 첫 번째 요청이 동일한 카운트 출력이있을 것이다 절전 모드로 전환하면서

<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); 
} 

모든 페이지가 대기.

+0

WebDev에서 테스트 중입니까? 멀티 코어 서버에서 IIS와 다르게 동작합니다. –

+0

@Craig : IIS 7.5, 쿼드 코어의 Windows 7 x64를 사용하여 테스트 –

+0

이상하게 보입니다. 아마도 당신은 디버그 모드를 사용하고 있습니까? 이것은 정말로 * 잠그면 안됩니다. 다른 요청은 캐시 실패를 가져와야합니다. –

1

도움이 될 수있는 작은 테스트를 만들었습니다. 내가 발견 한 것은 캐시되지 않은 요청이 차단되지 않으며 캐시가 만료되고 작업이 완료되기 전에 오는 각 요청이 해당 작업을 트리거한다는 것입니다.

예를 들어, 아래 코드는 내 시스템에서 Cassini를 사용하는 데 약 6-9 초 걸립니다. 약 2 초 간격으로 두 개의 요청 (예 : 두 개의 브라우저 탭)을 보내면 둘 다 고유 한 결과를 받게됩니다. 마지막으로 완료 할 요청은 후속 요청에 대해 캐시 된 응답이기도합니다.

// 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

이전 질문이지만이 문제로 달려 들어 조사를했습니다.

예제 코드 : 하나 개의 브라우저에서

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

실행을, 그리고 잠금 기다려야 할 것 같다.

IE와 Firefox에서 테스트 한 다른 브라우저에서 실행하면 요청이 보류되지 않습니다.

따라서 "올바른"동작은 IIS의 기능보다 사용중인 브라우저와 관련이 있습니다.

편집 : 명확히하려면 - 잠금 없음. 서버는 첫 번째 결과가 캐싱되기 전에 들어 오기를 관리하는 모든 요청에 ​​의해 공격을받습니다. 그 결과 무거운 요청에 대해 서버에 큰 타격을 줄 수 있습니다. (또는 외부 시스템을 호출하면 서버가 많은 요청을 처리 할 경우 시스템이 다운 될 수 있습니다 ...)

0

이 정보를 확인하십시오. here : "서버에 동시에 여러 요청을하는 단일 클라이언트가 있습니다 기본적으로 이러한 요청은 직렬화됩니다. "

따라서 단일 클라이언트의 동시 요청이 직렬화되면 후속 요청에서 캐시를 사용합니다. (* mats-nilsson 및 @ nick-craver) 위의 답변에서 일부 동작이 나타나는 것 같습니다.

당신이 우리에게 보여 주신 컨텍스트는 여러 명의 사용자로, 동시에 서버에 충돌하게됩니다. 하나 이상의 요청을 완료하고 출력 캐시를 작성하고 다음 요청에 사용할 때까지 따라서 동일한 리소스를 요청하는 여러 사용자를 직렬화하려는 경우 직렬화 된 요청이 단일 사용자에 대해 어떻게 작동하는지 이해해야합니다. 너가 원하는게 그거야?