asp.net - मैंने अभी पाया है कि सभी एएसपी.Net वेबसाइटें धीमी क्यों हैं, और मैं इसके बारे में क्या करने के लिए काम करने की कोशिश कर रहा हूं




performance session (6)

इस समस्या के साथ किसी को भी मदद करने के लिए (उसी सत्र से दूसरे को निष्पादित करते समय अनुरोध लॉक करना) ...

आज मैंने इस मुद्दे को हल करना शुरू कर दिया और कुछ घंटों के शोध के बाद, मैंने Global.asax फ़ाइल से Session_Start विधि (यहां तक ​​कि खाली होने पर) को हटाकर हल किया।

यह मैंने परीक्षण की सभी परियोजनाओं में काम करता है।

मैंने अभी पाया है कि एएसपी.Net वेब एप्लिकेशन में प्रत्येक अनुरोध को अनुरोध की शुरुआत में सत्र लॉक मिलता है, और फिर अनुरोध के अंत में इसे जारी करता है!

यदि इसके प्रभाव आपके ऊपर खो गए हैं, क्योंकि यह मेरे लिए पहले था, तो इसका मूल रूप से निम्नलिखित अर्थ है:

  • कभी भी एक एएसपी.Net वेबपृष्ठ लोड करने में काफी समय लग रहा है (शायद धीमी डेटाबेस कॉल या जो कुछ भी हो), और उपयोगकर्ता निर्णय लेता है कि वे एक अलग पृष्ठ पर नेविगेट करना चाहते हैं क्योंकि वे प्रतीक्षा करने के थक गए हैं, वे नहीं कर सकते! ASP.Net सत्र लॉक नए पृष्ठ अनुरोध को तब तक प्रतीक्षा करने के लिए मजबूर करता है जब तक कि मूल अनुरोध ने दर्दनाक धीमी गति समाप्त नहीं की हो। Arrrgh।

  • कभी भी एक अपडेटपैनल धीरे-धीरे लोड हो रहा है, और उपयोगकर्ता अपडेटपेनल अपडेट करने से पहले किसी भिन्न पृष्ठ पर नेविगेट करने का निर्णय लेता है ... वे नहीं कर सकते! एएसपीनेट सत्र लॉक नए पृष्ठ अनुरोध को तब तक इंतजार करने के लिए मजबूर करता है जब तक कि मूल अनुरोध ने दर्दनाक धीमी गति समाप्त नहीं की हो। डबल Arrrgh!

तो, विकल्प क्या हैं? अब तक मैं साथ आया हूं:

  • एक कस्टम सत्रस्टेटडेटास्टोर लागू करें, जो एएसपी.NET का समर्थन करता है। मुझे प्रतिलिपि बनाने के लिए बहुत सारे लोग नहीं मिला है, और ऐसा लगता है कि यह उच्च जोखिम और गड़बड़ करने में आसान है।
  • प्रगति पर सभी अनुरोधों का ट्रैक रखें, और यदि एक ही उपयोगकर्ता से अनुरोध आता है, तो मूल अनुरोध रद्द करें। बहुत चरम लगता है, लेकिन यह काम करेगा (मुझे लगता है)।
  • सत्र का उपयोग न करें! जब मुझे उपयोगकर्ता के लिए किसी प्रकार की स्थिति की आवश्यकता होती है, तो मैं इसके बजाय कैश का उपयोग कर सकता हूं, और प्रमाणित उपयोगकर्ता नाम, या ऐसी कुछ चीज़ों पर महत्वपूर्ण आइटम। फिर चरम लगता है।

मैं वास्तव में विश्वास नहीं कर सकता कि एएसपी.Net माइक्रोसॉफ्ट टीम ने संस्करण 4.0 पर ढांचे में इतनी बड़ी प्रदर्शन बाधा छोड़ी होगी! क्या मुझसे साफ़ - साफ़ कुछ चीज़ चूक रही है? सत्र के लिए थ्रेडसेफ संग्रह का उपयोग करना कितना मुश्किल होगा?


एएसपीएनईटी एमवीसी के लिए, हमने निम्नलिखित किया:

  1. डिफ़ॉल्ट रूप से, SessionStateBehavior.ReadOnly सेट करें। केवल डिफ़ॉल्ट नियंत्रक SessionStateBehavior.ReadOnly को ओवरराइड करके सभी नियंत्रक की कार्रवाई पर DefaultControllerFactory
  2. सत्र स्थिति में लिखने की आवश्यकता वाले नियंत्रक कार्यों पर, SessionStateBehaviour.Required पर सेट करने के लिए विशेषता के साथ चिह्नित करें। आवश्यक

कस्टम कंट्रोलर GetControllerSessionBehaviour बनाएं और GetControllerSessionBehaviour ओवरराइड GetControllerSessionBehaviour

    protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)
    {
        var DefaultSessionStateBehaviour = SessionStateBehaviour.ReadOnly;

        if (controllerType == null)
            return DefaultSessionStateBehaviour;

        var isRequireSessionWrite =
            controllerType.GetCustomAttributes<AcquireSessionLock>(inherit: true).FirstOrDefault() != null;

        if (isRequireSessionWrite)
            return SessionStateBehavior.Required;

        var actionName = requestContext.RouteData.Values["action"].ToString();
        MethodInfo actionMethodInfo;

        try
        {
            actionMethodInfo = controllerType.GetMethod(actionName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
        }
        catch (AmbiguousMatchException)
        {
            var httpRequestTypeAttr = GetHttpRequestTypeAttr(requestContext.HttpContext.Request.HttpMethod);

            actionMethodInfo =
                controllerType.GetMethods().FirstOrDefault(
                    mi => mi.Name.Equals(actionName, StringComparison.CurrentCultureIgnoreCase) && mi.GetCustomAttributes(httpRequestTypeAttr, false).Length > 0);
        }

        if (actionMethodInfo == null)
            return DefaultSessionStateBehaviour;

        isRequireSessionWrite = actionMethodInfo.GetCustomAttributes<AcquireSessionLock>(inherit: false).FirstOrDefault() != null;

         return isRequireSessionWrite ? SessionStateBehavior.Required : DefaultSessionStateBehaviour;
    }

    private static Type GetHttpRequestTypeAttr(string httpMethod) 
    {
        switch (httpMethod)
        {
            case "GET":
                return typeof(HttpGetAttribute);
            case "POST":
                return typeof(HttpPostAttribute);
            case "PUT":
                return typeof(HttpPutAttribute);
            case "DELETE":
                return typeof(HttpDeleteAttribute);
            case "HEAD":
                return typeof(HttpHeadAttribute);
            case "PATCH":
                return typeof(HttpPatchAttribute);
            case "OPTIONS":
                return typeof(HttpOptionsAttribute);
        }

        throw new NotSupportedException("unable to determine http method");
    }

AcquireSessionLockAttribute

[AttributeUsage(AttributeTargets.Method)]
public sealed class AcquireSessionLock : Attribute
{ }

global.asax.cs में बनाए गए नियंत्रक फैक्ट्री को हुक अप करें

ControllerBuilder.Current.SetControllerFactory(typeof(DefaultReadOnlySessionStateControllerFactory));

अब, हम एक ही Controller में read-only read-write और read-write सत्र स्थिति दोनों ही रख सकते हैं।

public class TestController : Controller 
{
    [AcquireSessionLock]
    public ActionResult WriteSession()
    {
        var timeNow = DateTimeOffset.UtcNow.ToString();
        Session["key"] = timeNow;
        return Json(timeNow, JsonRequestBehavior.AllowGet);
    }

    public ActionResult ReadSession()
    {
        var timeNow = Session["key"];
        return Json(timeNow ?? "empty", JsonRequestBehavior.AllowGet);
    }
}

नोट: एएसपीएनईटी सत्र स्थिति अभी भी रीडोनली मोड में भी लिखी जा सकती है और किसी भी प्रकार के अपवाद को फेंक नहीं देगी (यह स्थिरता की गारंटी के लिए लॉक नहीं है) इसलिए हमें कंट्रोलर के कार्यों में AcquireSessionLock को चिह्नित करने के लिए सावधान रहना होगा जिसके लिए लेखन सत्र स्थिति की आवश्यकता होती है ।


जब तक आपके आवेदन की विशेष आवश्यकता नहीं है, मुझे लगता है कि आपके पास 2 दृष्टिकोण हैं:

  1. बिल्कुल सत्र का उपयोग न करें
  2. सत्र का प्रयोग करें और जेल का उल्लेख करते हुए ठीक ट्यूनिंग करें।

सत्र न केवल थ्रेड-सुरक्षित बल्कि राज्य-सुरक्षित भी है, इस तरह से कि आप जानते हैं कि जब तक वर्तमान अनुरोध पूरा नहीं हो जाता है, तो प्रत्येक सत्र परिवर्तक किसी अन्य सक्रिय अनुरोध से नहीं बदलता है। ऐसा होने के लिए आपको यह सुनिश्चित करना होगा कि वर्तमान अनुरोध पूरा होने तक सत्र लॉक हो जाएगा।

आप कई तरीकों से व्यवहार जैसे सत्र बना सकते हैं, लेकिन यदि यह वर्तमान सत्र को लॉक नहीं करता है, तो यह 'सत्र' नहीं होगा।

आपके द्वारा उल्लिखित विशिष्ट समस्याओं के लिए मुझे लगता है कि आपको HttpContext.Current.Response.IsClientConnected की जांच करनी चाहिए। यह अनावश्यक निष्पादन को रोकने और क्लाइंट पर इंतजार करने के लिए उपयोगी हो सकता है, हालांकि यह पूरी तरह से इस समस्या को हल नहीं कर सकता है, क्योंकि इसका उपयोग केवल पूलिंग तरीके से किया जा सकता है, न कि एसिंक।


ठीक है, जोएल मुलर को अपने सभी इनपुट के लिए इतनी बड़ी प्रॉप्स। मेरा अंतिम समाधान इस एमएसडीएन आलेख के अंत में विस्तृत कस्टम सत्रस्टेट मॉड्यूल का उपयोग करना था:

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx

यह था:

  • लागू करने के लिए बहुत तेज़ (प्रदाता मार्ग जाने से वास्तव में आसान लग रहा था)
  • बॉक्स के बाहर मानक मानक एएसपी.Net सत्र हैंडलिंग का उपयोग किया जाता है (सत्रस्टेट यूटिलिटी क्लास के माध्यम से)

इसने हमारे आवेदन में "स्नैपनेस" की भावना के लिए एक बड़ा अंतर बना दिया है। मैं अभी भी विश्वास नहीं कर सकता कि एएसपी.Net सत्र के कस्टम कार्यान्वयन पूरे अनुरोध के लिए सत्र लॉक करता है। यह वेबसाइटों के लिए इतनी बड़ी आलस्यता जोड़ता है। मुझे ऑनलाइन शोध की मात्रा से निर्णय लेना पड़ा (और कई वास्तव में अनुभवी एएसपी.Net डेवलपर्स के साथ वार्तालाप), बहुत से लोगों ने इस मुद्दे का अनुभव किया है, लेकिन बहुत कम लोगों को कभी भी कारण के निचले भाग में नहीं मिला है। शायद मैं स्कॉट गुजरात को एक पत्र लिखूंगा ...

मुझे आशा है कि इससे कुछ लोगों को वहां मदद मिलेगी!


मैंने इस थ्रेड में पोस्ट किए गए लिंक के आधार पर लाइब्रेरी तैयार की है। यह एमएसडीएन और कोडप्रोजेक्ट के उदाहरणों का उपयोग करता है। जेम्स के लिए धन्यवाद।

मैंने जोएल म्यूएलर द्वारा सलाह दी गई संशोधनों को भी बनाया।

कोड यहां है:

https://github.com/dermeister0/LockFreeSessionState

हैशटेबल मॉड्यूल:

Install-Package Heavysoft.LockFreeSessionState.HashTable

स्केलऑट स्टेटसेवर मॉड्यूल:

Install-Package Heavysoft.LockFreeSessionState.Soss

कस्टम मॉड्यूल:

Install-Package Heavysoft.LockFreeSessionState.Common

यदि आप Memcached या Redis के समर्थन को कार्यान्वित करना चाहते हैं, तो इस पैकेज को स्थापित करें। फिर LockFreeSessionState मॉड्यूल क्लास का वारिस करें और अमूर्त तरीकों को लागू करें।

कोड अभी तक उत्पादन पर परीक्षण नहीं किया गया है। त्रुटि प्रबंधन में सुधार करने की भी आवश्यकता है। मौजूदा कार्यान्वयन में अपवाद नहीं पकड़े गए हैं।

रेडिस का उपयोग कर कुछ लॉक-फ्री सत्र प्रदाता:


यदि आपका पृष्ठ किसी भी सत्र चर को संशोधित नहीं करता है, तो आप इस लॉक से अधिकतर ऑप्ट आउट कर सकते हैं।

<% @Page EnableSessionState="ReadOnly" %>

यदि आपका पृष्ठ किसी भी सत्र चर को नहीं पढ़ता है, तो आप उस पृष्ठ के लिए पूरी तरह से इस लॉक से ऑप्ट आउट कर सकते हैं।

<% @Page EnableSessionState="False" %>

यदि आपके कोई भी पृष्ठ सत्र चर का उपयोग नहीं करता है, तो web.config में सत्र स्थिति बंद करें।

<sessionState mode="Off" />

मैं उत्सुक हूं, आपको लगता है कि "थ्रेडसेफ संग्रह" थ्रेड-सुरक्षित बनने के लिए क्या करेगा, अगर यह ताले का उपयोग नहीं करता है?

संपादित करें: मुझे शायद "इस लॉक से अधिकतर ऑप्ट आउट" से मेरा क्या मतलब है, इसकी व्याख्या करनी चाहिए। एक-दूसरे को अवरुद्ध किए बिना एक ही सत्र में किसी भी सत्र के लिए केवल पढ़ने-सत्र-सत्र या नो-सत्र पृष्ठों को संसाधित किया जा सकता है। हालांकि, एक पठन-लेखन-सत्र पृष्ठ प्रसंस्करण शुरू नहीं कर सकता है जब तक कि सभी रीड-ओनली अनुरोध पूर्ण नहीं हो जाते हैं, और जब यह चल रहा है, तो स्थिरता बनाए रखने के लिए उस उपयोगकर्ता के सत्र में विशेष पहुंच होनी चाहिए। व्यक्तिगत मानों पर लॉकिंग काम नहीं करेगा, क्योंकि क्या होगा यदि एक पृष्ठ समूह के रूप में संबंधित मानों का एक सेट बदलता है? आप कैसे सुनिश्चित करेंगे कि एक ही समय में चल रहे अन्य पृष्ठों को उपयोगकर्ता के सत्र चर के निरंतर दृश्य मिलेगा?

मैं सुझाव दूंगा कि यदि संभव हो तो सेट करने के बाद आप सत्र चर के संशोधित को कम करने का प्रयास करें। यह आपको अपने अधिकांश पृष्ठों को केवल-पढ़ने-सत्र पृष्ठों को बनाने की अनुमति देगा, जिससे एक ही उपयोगकर्ता के एकाधिक एक साथ अनुरोध एक-दूसरे को अवरुद्ध नहीं करेंगे।





architecture