हमें प्रतिक्रिया समय में अचानक स्पाइक क्यों मिलता है?


12

हमारे पास एक एपीआई है जो कि IIS में होस्टेड ServiceStack का उपयोग करके कार्यान्वित किया जाता है। एपीआई की लोड टेस्टिंग करते हुए हमने पाया कि रिस्पॉन्स टाइम अच्छा है, लेकिन जैसे ही हम प्रति सर्वर लगभग 3,500 समवर्ती उपयोगकर्ताओं को मारते हैं, वे तेजी से बिगड़ते हैं। हमारे पास दो सर्वर हैं और 7,000 उपयोगकर्ताओं के साथ उन्हें मारने पर औसत प्रतिक्रिया समय सभी समापन बिंदुओं के लिए 500ms से नीचे बैठते हैं। बक्से एक लोड बैलेंसर के पीछे होते हैं, इसलिए हमें प्रति सर्वर 3,500 कंसंट्रेट मिलते हैं। हालांकि जैसे ही हम कुल समवर्ती उपयोगकर्ताओं की संख्या बढ़ाते हैं, हमें प्रतिक्रिया समय में उल्लेखनीय वृद्धि होती है। समवर्ती उपयोगकर्ताओं को 5,000 प्रति सर्वर तक बढ़ाने से हमें औसत प्रतिक्रिया समय लगभग 7 सेकंड के प्रति समापन बिंदु मिलता है।

सर्वर पर मेमोरी और सीपीयू काफी कम हैं, जबकि रिस्पॉन्स टाइम अच्छा है और खराब होने के बाद दोनों। 10,000 समवर्ती उपयोगकर्ताओं के साथ चरम पर, CPU का औसत 50% से कम है और RAM 16 में से 3-4 GB के आसपास बैठता है। यह हमें यह सोचकर छोड़ देता है कि हम कहीं न कहीं किसी प्रकार की सीमा मार रहे हैं। नीचे स्क्रीनशॉट कुल 10,000 समवर्ती उपयोगकर्ताओं के साथ लोड परीक्षण के दौरान परफ्यूम में कुछ प्रमुख काउंटर दिखाता है। हाइलाइट किया गया काउंटर अनुरोध / दूसरा है। स्क्रीनशॉट के दाईं ओर आप प्रति सेकंड ग्राफ़ को वास्तव में अनिश्चित होते हुए देख सकते हैं। यह धीमी प्रतिक्रिया समय के लिए मुख्य संकेतक है। जैसे ही हम इस पैटर्न को देखते हैं हम लोड टेस्ट में धीमी प्रतिक्रिया समय नोटिस करते हैं।

प्रति सेकंड अनुरोध के साथ perfmon स्क्रीनशॉट पर प्रकाश डाला गया

हम इस प्रदर्शन समस्या का निवारण कैसे करेंगे? हम यह पहचानने की कोशिश कर रहे हैं कि क्या यह कोई कोडिंग समस्या या कॉन्फ़िगरेशन समस्या है। क्या web.config या IIS में ऐसी कोई सेटिंग है जो इस व्यवहार की व्याख्या कर सकती है? अनुप्रयोग पूल .NET v4.0 चल रहा है और IIS संस्करण 7.5 है। डिफ़ॉल्ट सेटिंग्स से हमने जो एकमात्र बदलाव किया है, वह है एप्लीकेशन पूल क्यू लंबाई की वैल्यू को 1,000 से 5,000 तक अपडेट करना। हमने Aspnet.config फ़ाइल में निम्न कॉन्फ़िगरेशन सेटिंग्स भी जोड़ी हैं:

<system.web>
    <applicationPool 
        maxConcurrentRequestsPerCPU="5000"
        maxConcurrentThreadsPerCPU="0" 
        requestQueueLimit="5000" />
</system.web>

अधिक जानकारी:

एपीआई का उद्देश्य विभिन्न बाहरी स्रोतों से डेटा को संयोजित करना और JSON के रूप में वापस करना है। यह वर्तमान में डेटा लेयर में अलग-अलग बाहरी कॉल को कैश करने के लिए इनमेमोरी कैश कार्यान्वयन का उपयोग कर रहा है। संसाधन के लिए पहला अनुरोध आवश्यक सभी डेटा प्राप्त करेगा और उसी संसाधन के बाद के किसी भी अनुरोध को कैश से परिणाम प्राप्त होंगे। हमारे पास एक 'कैश रनर' है जिसे एक पृष्ठभूमि प्रक्रिया के रूप में लागू किया गया है जो कुछ निश्चित अंतराल पर कैश में जानकारी को अपडेट करता है। हमने बाहरी संसाधनों से डेटा लाने वाले कोड के चारों ओर लॉकिंग जोड़ दी है। हमने एक अतुल्यकालिक फैशन में बाहरी स्रोतों से डेटा लाने के लिए सेवाओं को भी लागू किया है ताकि समापन बिंदु केवल सबसे धीमी बाहरी कॉल के रूप में धीमा हो (जब तक कि हमारे पास निश्चित रूप से कैश में डेटा न हो)। यह System.Threading.Tasks.Task क्लास का उपयोग करके किया जाता है।क्या हम प्रक्रिया के लिए उपलब्ध थ्रेड्स की संख्या के संदर्भ में एक सीमा तक मार कर सकते हैं?


5
आपके CPU में कितने कोर हैं? शायद आप एक कोर को अधिकतम कर रहे हैं। जब जादू की संख्या 50%, 25% या 12.5% ​​होती है, तो यह बताता है कि आपने एक कोर को अधिकतम कर दिया है और किसी कारण से निष्क्रिय बैठे अन्य कोर का उपयोग करने में सक्षम नहीं हैं। एक अधिकतम बाहर कोर के लिए जाँच करें।
डेविड श्वार्ट्ज

1
क्या आपको प्रति अनुरोध एक धागा मिला है? तो 5000 अनुरोधों के लिए आपको 5000 धागे मिले हैं? यदि आप ऐसा करते हैं तो आपकी समस्या की संभावना है। इसके बजाय आपको थ्रेड पूल बनाना चाहिए और थ्रेड पूल का उपयोग अनुरोधों को संसाधित करने के लिए करना चाहिए, अनुरोधों को कतारबद्ध करते हुए जैसे वे थ्रेड पूल में आते हैं। जब एक धागा एक अनुरोध के साथ समाप्त हो गया है तो यह कतार से अनुरोध को संसाधित कर सकता है। स्टैकओवरफ्लो के लिए इस तरह की चर्चा सबसे अच्छी है। बहुत सारे थ्रेड्स का अर्थ बहुत अधिक संदर्भ स्विच है।
मैट

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

1
+1 से ऊपर डेविड्स सुझाव। आपको वास्तव में परीक्षण को फिर से करना चाहिए और प्रत्येक मुख्य उपयोग को ध्यान से देखना चाहिए। मेरा सुझाव है कि यदि आप और कुछ नहीं तो इसे खत्म करने के लिए आप इस asap करते हैं। दूसरी बात, मुझे आपके कैशे पर थोड़ा शक है। लॉक कंटेस्टेंट वास्तव में इस तरह का व्यवहार दिखा सकता है - कुछ महत्वपूर्ण बिंदुओं पर ताले देरी का कारण बनते हैं, जिसके कारण ताले सामान्य से अधिक समय तक आयोजित होते हैं, जिससे एक टिपिंग बिंदु होता है जहां चीजें तेजी से नीचे जाती हैं। क्या आप अपना कैशिंग और लॉकिंग कोड साझा कर सकते हैं?
बावर्ची खाना पकाने

1
सर्वरों के लिए डिस्क सेटअप क्या है (यह मानते हुए कि चूंकि वे संतुलित हैं डिस्क सेटअप एक समान है)? क्या आप अपने शुरुआती पोस्ट में ड्राइव / सर्वर के लिए सभी चश्मा पोस्ट कर सकते हैं? क्या आपने भौतिक ड्राइव (डिस्क) पर आईआईएस और आईआईएस लॉग फाइल पर डिस्क पर एक परफॉमेंस फेंका है? यह बहुत संभव है कि आप उस 3,500 अनुरोध = 3,500+ IIS लॉग एंट्री में डिस्क के साथ समस्याओं का सामना कर रहे हों। यदि वे एक ही डिस्क / विभाजन पर हैं तो आपको वहाँ एक बड़ी समस्या हो सकती है।
टेची जो

जवाबों:


2

@DavidSchwartz और @Matt के साथ यह एक थ्रेड जैसा दिखता है, लॉकिंग इश्यू को मैनेज करता है।

मैं सुझाव देता हूँ:

  1. बाहरी कॉल और उनके लिए उत्पन्न कैश को फ्रीज करें और सर्वर - पर्यावरण पक्ष से संबंधित किसी भी मुद्दे को छोड़ने के लिए स्थिर बाहरी जानकारी के साथ लोड टेस्ट चलाएं।

  2. यदि उनका उपयोग नहीं कर रहे हैं तो थ्रेड पूल का उपयोग करें।

  3. बाहरी कॉल के बारे में आपने कहा "हमने एक अतुल्यकालिक फैशन में बाहरी स्रोतों से डेटा लाने के लिए सेवाओं को भी लागू किया है ताकि समापन बिंदु केवल सबसे धीमी बाहरी कॉल के रूप में धीमा हो (जब तक कि हमारे पास निश्चित रूप से कैश में डेटा न हो)।" "

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

यदि समस्या अभी भी बनी रहती है, तो मेरा सुझाव है कि टास्क क्लास से बचें और उसी थ्रेड पूल के माध्यम से बाहरी कॉल करें जो उपयोगकर्ता के अनुरोधों का प्रबंधन करता है। यह पिछले परिदृश्य से बचने के लिए है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.