हमारे पास एक एपीआई है जो कि IIS में होस्टेड ServiceStack का उपयोग करके कार्यान्वित किया जाता है। एपीआई की लोड टेस्टिंग करते हुए हमने पाया कि रिस्पॉन्स टाइम अच्छा है, लेकिन जैसे ही हम प्रति सर्वर लगभग 3,500 समवर्ती उपयोगकर्ताओं को मारते हैं, वे तेजी से बिगड़ते हैं। हमारे पास दो सर्वर हैं और 7,000 उपयोगकर्ताओं के साथ उन्हें मारने पर औसत प्रतिक्रिया समय सभी समापन बिंदुओं के लिए 500ms से नीचे बैठते हैं। बक्से एक लोड बैलेंसर के पीछे होते हैं, इसलिए हमें प्रति सर्वर 3,500 कंसंट्रेट मिलते हैं। हालांकि जैसे ही हम कुल समवर्ती उपयोगकर्ताओं की संख्या बढ़ाते हैं, हमें प्रतिक्रिया समय में उल्लेखनीय वृद्धि होती है। समवर्ती उपयोगकर्ताओं को 5,000 प्रति सर्वर तक बढ़ाने से हमें औसत प्रतिक्रिया समय लगभग 7 सेकंड के प्रति समापन बिंदु मिलता है।
सर्वर पर मेमोरी और सीपीयू काफी कम हैं, जबकि रिस्पॉन्स टाइम अच्छा है और खराब होने के बाद दोनों। 10,000 समवर्ती उपयोगकर्ताओं के साथ चरम पर, CPU का औसत 50% से कम है और RAM 16 में से 3-4 GB के आसपास बैठता है। यह हमें यह सोचकर छोड़ देता है कि हम कहीं न कहीं किसी प्रकार की सीमा मार रहे हैं। नीचे स्क्रीनशॉट कुल 10,000 समवर्ती उपयोगकर्ताओं के साथ लोड परीक्षण के दौरान परफ्यूम में कुछ प्रमुख काउंटर दिखाता है। हाइलाइट किया गया काउंटर अनुरोध / दूसरा है। स्क्रीनशॉट के दाईं ओर आप प्रति सेकंड ग्राफ़ को वास्तव में अनिश्चित होते हुए देख सकते हैं। यह धीमी प्रतिक्रिया समय के लिए मुख्य संकेतक है। जैसे ही हम इस पैटर्न को देखते हैं हम लोड टेस्ट में धीमी प्रतिक्रिया समय नोटिस करते हैं।
हम इस प्रदर्शन समस्या का निवारण कैसे करेंगे? हम यह पहचानने की कोशिश कर रहे हैं कि क्या यह कोई कोडिंग समस्या या कॉन्फ़िगरेशन समस्या है। क्या 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 क्लास का उपयोग करके किया जाता है।क्या हम प्रक्रिया के लिए उपलब्ध थ्रेड्स की संख्या के संदर्भ में एक सीमा तक मार कर सकते हैं?