2010-01-29 22 views
8

मान लें कि, सैद्धांतिक रूप से, मेरे पास मेरी वेबसाइट में एक पृष्ठ/नियंत्रक कार्रवाई है जो कुछ बहुत भारी चीजें करता है। इसे अपने ऑपरेशन को पूरा करने में लगभग 10 सेकंड लगते हैं।एएसपी.नेट (एमवीसी) आउटपुट कैश और समवर्ती अनुरोध

अब, मैं इसे 15 मिनट के लिए कैश करने के लिए .NET के आउटपुट कैश तंत्र का उपयोग करता हूं (परीक्षा के लिए, मैं [OutputCache(Duration = 900)] का उपयोग करता हूं) क्या होता है, 15 मिनट के बाद, कैश की समयसीमा समाप्त हो जाती है और 100 उपयोगकर्ता फिर से उन 10 सेकंड के भीतर पृष्ठ का अनुरोध करते हैं भारी प्रसंस्करण करने में लगता है?

  1. भारी सामान केवल पहली बार किया जाता है, और वहाँ कुछ ताला तंत्र है ताकि अन्य 99 उपयोगकर्ताओं कैश परिणाम
  2. भारी सामान 100 बार किया जाता है (और सर्वर के रूप में अपंग है मिल जाएगा इसमें 100 * 10 सेकंड तक लग सकते हैं)

शायद आसान सवाल है, लेकिन मैं 100% निश्चित नहीं हूं। मुझे उम्मीद है कि यह नंबर एक है, हालांकि :-)

धन्यवाद!

उत्तर

4

अच्छा, यह इस बात पर निर्भर करता है कि आपके पास आईआईएस कॉन्फ़िगर किया गया है। यदि आपके पास 100 से कम कार्यकर्ता धागे हैं (मान लें, 50), तो "भारी सामान" 50 बार किया जाता है, जो आपके सर्वर को अपंग करता है, और फिर शेष 50 अनुरोध कैश से परोसे जाएंगे।

लेकिन नहीं, कैश किए गए एक्शन परिणाम पर कोई "लॉकिंग तंत्र" नहीं है; यह अधिकांश भाग के लिए प्रतिकूल होगा।

संपादित करें: मुझे विश्वास है कि यह सच है, लेकिन निक के परीक्षण अन्यथा कहते हैं, और मेरे पास अब परीक्षण करने का समय नहीं है। यह अपने आप का प्रयास करें! बाकी का जवाब उपर्युक्त पर निर्भर नहीं है, और मुझे लगता है कि यह अधिक महत्वपूर्ण है।

आम तौर पर, हालांकि, कोई वेब अनुरोध, कैश या अन्यथा, वापसी के लिए 10 सेकंड का समय लेना चाहिए। अगर मैं आपके जूते में था, तो मैं किसी भी तरह से अनुरोध के कठिन भाग को पूर्व-गणना करने पर विचार करता हूं। यदि आप HTML को कैश करना चाहते हैं तो भी आप कार्रवाई परिणाम कैश कर सकते हैं, लेकिन ऐसा लगता है कि आपकी समस्या कुछ हद तक बड़ी है।

आप भी consider asynchronous controllers चाहते हैं। अंत में, ध्यान दें कि हालांकि आईआईएस और एएसपी.नेट एमवीसी इस भारी गणना पर बंद नहीं होगा, आप कर सकते हैं। यदि आप गणना पर लॉक के साथ संयुक्त एसिंक्रोनस नियंत्रकों का उपयोग करते हैं, तो आप प्रभावी रूप से उस व्यवहार को प्राप्त करेंगे जो आप पूछ रहे हैं। मैं वास्तव में यह नहीं कह सकता कि क्या आपके काम के बारे में और जानने के बिना यह सबसे अच्छा समाधान है।

+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 विधि में एक ब्रेकपाइंट पूरी करता है। .. यह पूरा करने के लिए पहले व्यक्ति की प्रतीक्षा करता है और उस परिणाम को उन सभी को देता है जिन्होंने उस पृष्ठ का अनुरोध किया है।

नोट: वेबफॉर्म परिदृश्य में परीक्षण करना आसान था, लेकिन यह फ्रेमवर्क का एक साझा पहलू है, आप उसी परिणाम के साथ एमवीसी में एक ही परीक्षण कर सकते हैं।

यहां परीक्षण का एक वैकल्पिक तरीका है:

<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

क्या आप वेबडेव पर परीक्षण कर रहे हैं? यह एक बहु-कोर सर्वर पर आईआईएस की तुलना में * बहुत * अलग व्यवहार करता है। –

+0

@ क्रिएग: आईआईएस 7.5 का उपयोग करके परीक्षण, विंडोज 7 x64 क्वाड-कोर –

+0

पर यह अजीब लगता है। शायद आप डीबग मोड का उपयोग कर रहे हैं? यह वास्तव में * लॉक नहीं होना चाहिए। अन्य अनुरोधों को कैश मिस मिलना चाहिए। –

1

मैंने एक छोटा परीक्षण किया जो मदद कर सकता है। मेरा मानना ​​है कि मैंने जो खोजा है वह यह है कि अनचाहे अनुरोध अवरुद्ध नहीं होते हैं, और प्रत्येक अनुरोध जो कैश की समयसीमा समाप्त हो जाता है और कार्य पूरा होने से पहले भी उस कार्य को ट्रिगर करता है।

उदाहरण के लिए, नीचे दिए गए कोड में कैसिनी का उपयोग करके मेरे सिस्टम पर लगभग 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++); 
} 

भागो यह, और यह ताला और प्रतीक्षा करने के लिए लगता है।

इसे विभिन्न ब्राउज़रों में चलाएं (मैंने आईई और फ़ायरफ़ॉक्स में परीक्षण किया) और अनुरोधों को रोक नहीं दिया गया है।

तो आईआईएस में फ़ंक्शन की तुलना में आप जिस ब्राउज़र का उपयोग कर रहे हैं उसके साथ "सही" व्यवहार करना अधिक है।

संपादित करें: स्पष्टीकरण के लिए - कोई लॉक नहीं। सर्वर को उन सभी अनुरोधों से हिट किया जाता है जो पहले परिणाम कैश किए जाने से पहले प्राप्त होते हैं, संभवतः भारी अनुरोधों के लिए सर्वर पर हार्ड हिट होता है। (या यदि आप बाहरी सिस्टम को कॉल करते हैं, तो आपका सिस्टम कई अनुरोधों को पूरा करता है, तो उस सिस्टम को नीचे लाया जा सकता है ...)

0

आपको यह जानकारी जांचनी चाहिए here: "आपके पास एक ही क्लाइंट सर्वर पर एकाधिक समवर्ती अनुरोध करता है डिफ़ॉल्ट व्यवहार यह है कि इन अनुरोधों को क्रमबद्ध किया जाएगा; "

इसलिए, यदि एकल क्लाइंट के समवर्ती अनुरोध को क्रमबद्ध किया गया है, तो अगला अनुरोध कैश का उपयोग करेगा। इससे ऊपर कुछ जवाब (@ मैट्स-निल्सन और @ निक-क्रेवर) में कुछ व्यवहार दिखाई देते हैं।

जो संदर्भ आपने हमें दिखाया है वह एकाधिक उपयोगकर्ता है, जो आपको एक ही समय में सर्वर पर हिट करेगा, और आप सर्वर व्यस्त होंगे कम से कम एक अनुरोध पूरा करने तक और आउटपुट कैश बनाया है, और अगले अनुरोध के लिए इसका इस्तेमाल करें। इसलिए यदि आप एक ही संसाधन का अनुरोध करने वाले एकाधिक उपयोगकर्ताओं को क्रमबद्ध करना चाहते हैं, तो हमें यह समझने की आवश्यकता है कि धारावाहिक अनुरोध एकल उपयोगकर्ता के लिए कैसे काम करता है। क्या तुम यही चाहते हो?

संबंधित मुद्दे