2013-02-12 12 views
6

मेरे पास .NET 3.5 का उपयोग करके आईआईएस एक्सप्रेस (अंत में पूर्ण आईआईएस) में होस्ट किया गया एक काफी सरल डब्ल्यूसीएफ वेब सेवा है। सेवा विधि काफी हद तक अनिच्छुक है।सर्वर 500: बहुत से लंबित सुरक्षित बातचीत

[ServiceContract] 
public class MySvc 
{ 
    [OperationContract] 
    public Stuff MyMethod(string input) 
    { 
     Stuff result = DoSomething(); 
     return result; 
    } 
} 

सेवा विन्यास भी काफी सामान्य है:

<system.serviceModel> 
    <services> 
     <service behaviorConfiguration="MySvcBehavior" name="MySvc"> 
      <endpoint address="" binding="wsHttpBinding" contract="MySvc"> 
       <identity> 
        <dns value="localhost"/> 
       </identity> 
      </endpoint> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="MySvcBehavior"> 
       <serviceMetadata httpGetEnabled="true"/> 
       <serviceDebug includeExceptionDetailInFaults="false"/> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
</system.serviceModel> 

सेवा एक ASPX आवेदन में से एक कोड-पीछे सेवन किया जाता है। एक सेवा संदर्भ है, जो कुछ समान रूप से अनिच्छुक कोड का कारण बनता है।

MySvcClient svc = new MySvcClient(); 
Stuff result = svc.MyMethod("foo"); 

जब तक यह एक समय में एक अनुरोध है, सब कुछ ठीक काम करता है और ग्राहक कोड अपेक्षित परिणाम प्राप्त करता है। वाह।

समस्या तब आती है जब मैं कुछ बहुत ही प्राचीन तनाव परीक्षण करता हूं। मैं ब्राउज़र में क्लाइंट एएसपीएक्स पेज लोड करता हूं, और उसके बाद F5 कुंजी दबाता हूं। आईआईएस एक्सप्रेस विंडो को देखते हुए, पहले परिणाम 200 स्थिति के रूप में वापस आते हैं, लेकिन कुछ मिनटों के बाद मैं स्थिति 500 ​​देखना शुरू कर देता हूं। इस बिंदु पर, सेवा केवल आईआईएस एक्सप्रेस को पुनरारंभ करने तक स्थिति 500 ​​के साथ प्रतिक्रिया देगी। (लगभग 10 मिनट प्रतीक्षा करने के आधार पर।)

क्लाइंट कोड में ब्रेकपॉइंट सेट करना, मुझे पूरा रिटर्न संदेश है "सर्वर पर बहुत अधिक लंबित सुरक्षित बातचीतएं हैं। कृपया बाद में पुनः प्रयास करें।"

सर्वर कोड में ब्रेकपॉइंट सेट करना, मुझे लगता है कि मेरा कोड भी लागू नहीं किया जा रहा है। तो यह कॉल और मेरे कोड की वास्तविक शुरुआत के बीच कहीं भी विफल रहा है।

मेरी ऑनलाइन खोजें बहुत ही आशाजनक नहीं रही हैं, अधिकांशतः suggestion of writing a custom binding की ओर बढ़ रही है ताकि अधिकतम भुगतान करने वाली संपत्तियों को ओवरराइड किया जा सके और "किसी ने मुझे बताया कि एक [अज्ञात] कॉन्फ़िगरेशन फ़ाइल सेटिंग है" जो तब होता है टूटी हुई लिंक का दावा है कि माइक्रोसॉफ्ट ने इसे एक बग के रूप में स्वीकार किया है।

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

+2

क्या आपने 'उपयोग' कथन का उपयोग किया था? निपटान तक कनेक्शन खुला रखा जाएगा। जब तक कोई 'उपयोग' कथन न हो, कनेक्शन के सफाई को कचरा कलेक्टर द्वारा निर्धारित किया जाता है। – Caramiriel

+0

यह वास्तव में मेरे क्लाइंट-साइड कोड के साथ एक समस्या है। लेकिन स्थिति 500 ​​संदेशों का मतलब समीकरण के सर्वर पक्ष पर कुछ नाखुश है। – ThatBlairGuy

उत्तर

4

लगता है जैसे आपके पास सर्वर पर एक अरब खुले कनेक्शन हैं - क्लाइंट पक्ष कनेक्शन के लिए 'उपयोग' का उपयोग नहीं कर रहा है।

+0

मैं उस कथन के साथ बहस नहीं कर सकता। :-) लेकिन चूंकि मैं अच्छी तरह से लिखे जाने के लिए ग्राहकों को मजबूर नहीं कर सकता (स्वयं के अलावा), मैं इस समस्या के खिलाफ सबसे अच्छा बचाव कैसे करूं? – ThatBlairGuy

+0

अफसोस की बात यह है कि यह मूल रूप से (अनजाने में) एक डॉस हमला (सेवा अस्वीकार) है, इसके खिलाफ सुरक्षा करने का एकमात्र तरीका निष्क्रियता की अवधि के बाद कनेक्शन छोड़ना होगा। आपके परीक्षण मामले में, मुझे संदेह है कि इससे मदद मिलेगी जबतक कि आप वास्तव में कुछ ही सेकंड में टाइमआउट सेट नहीं कर सकते। –

+0

यह मूल रूप से निष्कर्ष है कि मैं भी पहुंच रहा हूं। – ThatBlairGuy

0

लक्षित सर्वर से बहुत सारे कनेक्शन हैं। कनेक्शन को उचित तरीके से बंद करने के कुछ तरीके हैं। पहले ही उल्लेख किया गया है कि हमेशा डब्ल्यूसीएफ प्रॉक्सी के आसपास using कथन होना चाहिए।

इसके अलावा, एक बग था (है?) एक बग जिसके लिए आपको प्रॉक्सी खोलते समय अनुरोध करने की आवश्यकता होती है। प्रॉक्सी बनाते समय, यह प्रॉक्सी को सर्वर से अनुरोध करने का मौका दो मिनट देता है। यदि ऐसा होता है, तो यह प्रॉक्सी की सफाई की अनुमति देता है, टाइमर को अमान्य करता है। अगर कोई अनुरोध नहीं किया गया था, तो प्रॉक्सी अभी भी कनेक्शन बंद करने से पहले टाइमआउट पर इंतजार कर रही है। संभवतः इस बार मामला नहीं, लेकिन पूर्णता के लिए जोड़ा गया।

इस के आसपास जाने का एक तरीका है (एएसपी.नेट) कैशिंग का उपयोग करना। System.Web.Caching.Cache इसके लिए एक अच्छा उम्मीदवार है। यह आपको किसी दिए गए (अंततः स्लाइडिंग) अवधि के परिणामों को कैश करने की अनुमति देता है। इस तरह से केवल 2 अनुरोध किए जा रहे हैं, 2 मिनट कहते हैं। यह वेबसाइट/webservice बहुत स्केलेबल बनाता है। उदाहरण के लिए, यदि प्रति मिनट 1000 अनुरोध हैं, तो उसी सेवा कॉल के लिए केवल एक कनेक्शन का उपयोग किया गया था।

यह अनुरोध करने का एक और तरीका है, अगर अनुरोध महंगा है और प्रतीक्षा करने के लायक नहीं है, तो अनुरोध को अग्रिम बनाने के लिए और प्रतिक्रिया को कैश करें (एला क्रॉन, टास्क शेड्यूलर या बस एक और थ्रेड)। यह पृष्ठों को तेजी से पुनर्प्राप्ति के लिए अनुमति देगा।

इसके अलावा, सर्वर को सही तरीके से कॉन्फ़िगर किया जाना चाहिए। एक ग्राहक से 128 समवर्ती कनेक्शन खोलने की आवश्यकता नहीं है। प्रति ग्राहक 8 कनेक्शन कहने के लिए इसे सीमित करने का प्रयास करें। यह एक ही समय में कई ग्राहकों को संभालने की अनुमति देता है। एक सभ्य टाइमआउट सेट करने का भी प्रयास करें। क्लाइंट के कनेक्शन को बंद करने के लिए 5 मिनट की प्रतीक्षा कर रहा है, वास्तव में थ्रूपुट नहीं बढ़ाता है।

भी asynchronous handling of messages पर विचार करें। यह उस समय का उपयोग करता है जब अतिरिक्त कनेक्शन को संभालने के लिए सेवा को I/O पर इंतजार करना पड़ता है। मैं नहीं देख सकता कि डब्ल्यूसीएफ सेवा क्या करती है, इसलिए यह प्रासंगिक नहीं हो सकता है।

+0

सहमत हैं, ये ग्राहक के लिए सभी अच्छे अभ्यास हैं। मुझे जो चाहिए वह ** सेवा ** के लिए एक खराब लिखित ग्राहक के खिलाफ खुद को बचाने का एक तरीका है। – ThatBlairGuy

1

मैं पहले सर्वर क्लास मशीन पर पूर्ण आईआईएस पर इसका परीक्षण करने का सुझाव दूंगा। मैं प्रदर्शन परीक्षण के लिए क्लाइंट ओएस पर आईआईएस एक्सप्रेस पर भरोसा नहीं करता।
यदि यह अभी भी खराब है तो maxConcurrentCalls को प्रतिबंधित करने के लिए थ्रॉटलिंग देखें। http://msdn.microsoft.com/en-us/library/vstudio/ms735114(v=vs.90).aspx

0

उपयोग करने वाले कथन की सिफारिश करने वालों के लिए: आपको ग्राहकों को बंद करने के लिए उपयोग करने वाले कथन का उपयोग नहीं करना चाहिए।

http://msdn.microsoft.com/en-us/library/aa355056.aspx

इसके बजाय देखें ग्राहकों को बंद करने के आप निम्नलिखित स्निपेट का उपयोग करना चाहिए: यदि आप स्पष्ट अपवाद कैश करने के लिए नहीं पसंद करते हैं

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

सर्वर पर लंबित बातचीत के आपके मुद्दे पर, यह आपके ग्राहक को सही तरीके से बंद करने के बाद यह कम आम हो जाएगा, हालांकि आप अभी भी इसे देख सकते हैं यदि आपके सर्वर साइड कोड में लंबे समय तक चलने वाला ऑपरेशन है और ग्राहक कतारबद्ध हैं। इस मामले में, MaxPendingChannels के मान को बढ़ाने के लिए आपको क्लाइंट और रिसीवर साइड कॉन्फ़िगरेशन फ़ाइलों दोनों में कस्टम बाध्यकारी का उपयोग करना होगा, या सेवा शुरू करने से पहले रिसीवर पक्ष पर बाध्यकारी रूप से संशोधित करना होगा। यदि आप .NET 3.5 का उपयोग कर रहे हैं तो MaxPendingChannels का डिफ़ॉल्ट मान वास्तव में 4 है। मूल्य .NET 3.0 के लिए 128 होने के लिए अधिकृत है। दोनों मेरी राय में कम हैं।

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/745b95d2-1480-4618-89f5-1339d6ee228d

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