2012-06-27 13 views
9

मैं एक प्रदर्शन परीक्षण पर काम कर रहा हूं जिसमें कई ग्राहक 150 से अधिक अनुरोधों के साथ सर्वर पर बमबारी करते हैं, जितनी जल्दी हो सके।मेरा एप्लिकेशन सिंक्रनाइज़ेशन के लिए इतना इंतजार क्यों करता है?

सर्वर 3 WCF सेवाओं से निर्माण किया है, एक httpbinding साथ बाहर के लिए खोला जाता है, यह net.pipe (आईपीसी) के माध्यम से 2 अन्य सेवाओं के लिए बात करता है। सेवाओं में से एक डीबी कनेक्शन (एसक्यूएल सर्वर 2008 आर 2) का प्रभारी है।

यह DB कनेक्शन सेवा निम्न कनेक्शन स्ट्रिंग enhancments उपयोग करता है:

Min Pool Size=20; Max Pool Size=1000; Connection Timeout=20; 

और WCF से रोक दिए (अन्य सभी WCF सेवाओं की तरह) है।

मैंने देखा है कि जब मैं 1 ग्राहक इसे सक्रिय 3 सेकंड लग सकते हैं, लेकिन जब मैं 3 ग्राहकों को सक्रिय यह 8-9 या अधिक समय लग सकता है।

मैं एसक्यूएल सर्वर प्रोफाइलर के साथ की जाँच को देखने के लिए कितने समवर्ती प्रक्रियाओं उपयोग किया जाता है, और मैंने देखा कि केवल बारे में 8 प्रक्रियाओं का इस्तेमाल किया जा रहा है।

तो मुझे एहसास हुआ कि कहीं सर्वर में अनुरोध समवर्ती संसाधित करने के बजाय पंक्तिबद्ध मिलता है।

(चींटियों सटीक होना करने के लिए) यह के नीचे मैं एक प्रदर्शन प्रोफाइलर का उपयोग किया है करने के लिए आदेश जो मुझे पता चला है कि समय का लगभग 70% पर बर्बाद किया गया था "तुल्यकालन

जब प्रतीक्षा कर रहा है मैं कॉल ग्राफ खोलने मैं दो चीजें हैं जो अजीब लग रही खोजने के लेकिन मुझे यकीन है कि वे क्या मतलब है नहीं कर रहा हूँ:

  1. System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke पेड़ के शीर्ष में इस्तेमाल किया जा रहा है, वह ठीक है समवर्ती प्रसंस्करण के लिए?
  2. सभी सिंक्रनाइज़ समस्याएं , ExecuteNonQuery, ExecuteReader की तरह, एसक्यूएल सर्वर गतिविधि के कुछ प्रकार शामिल और इतने पर

मैंने देखा है कि डीबी कनेक्शन सेवा एक दाल परियोजना का उपयोग करता है (कुछ विरासत कोड (जब मैं कॉल पेड़ की तह तक पहुंचने) दुर्भाग्य से) जो पूरी तरह से स्थिर है।

this को पढ़ने के बाद मुझे यकीन है कि अगर दाल के कोड समस्याग्रस्त है या नहीं, यहाँ एक संग्रहीत प्रक्रिया कॉल का एक नमूना है नहीं कर रहा हूँ।

public static int PerformStoredProcedure(string storedP,string ext,out string msg) 
    { 
     msg = ""; 
     SqlCommand command = GetSqlCommand(storedP,ext); 
     command.Connection.Open(); 
     int result = (int)PerformStoredProcedure(command,out msg); 
     command.Connection.Close(); 
     return result; 
    } 

इस विधि आमतौर पर डीबी कनेक्शन सेवा से कहा जाता है:

public static int PerformStoredProcedureWithParams(string storedP,string ext,out string msg, params object[] pars) 
    { 
     msg = ""; 
     SqlCommand command = GetSqlCommand(storedP,ext); 
     UpdateCommandParams(command, pars); 
     command.Connection.Open(); 
     int result = (int)PerformStoredProcedure(command,out msg); 
     command.Connection.Close(); 
     return result; 
    } 

तो, वहाँ कुछ भी गलत यहाँ है?

या शायद मुझे कहीं और देखना चाहिए?

संपादित करें:

बृजेश की टिप्पणी के बाद मैंने महसूस मैं डिफ़ॉल्ट InstanceContextMode और WCF सेवाओं के ConcurrencyMode बदल नहीं किया था ... शुरुआत की गलती का प्रकार मुझे लगता है।

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

मुझे क्या उपयोग करना चाहिए?

2 संपादित करें:

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

क्या ऐसा कोई अन्य कारण है कि ऐसा क्यों हो सकता है? मैं की संभावना से इनकार दाल एक समस्या जा रहा है क्योंकि पर्याप्त नहीं अनुरोध डीबी सेवा में जाना तो मैं सेवा या ग्राहकों में कुछ में अपनी कुछ समझ ...

3 संपादित करें:

यहाँ config फ़ाइलें :

प्रबंधक के config WCF सेवा अनुभाग:

<services> 
    <service behaviorConfiguration="ServicesBehavior" name="Verifone.GenericPP.GPPManagerService.GPPManagerServiceImpl"> 
    <host> 
     <baseAddresses> 
     <add baseAddress="http://localhost:9090/GPPManagerService/"/> 
     </baseAddresses> 
    </host> 
    <endpoint contract="Verifone.GenericPP.GPPManagerService.IGPPManagerService" binding="basicHttpBinding" address="GPPManagerService"></endpoint> 
    </service> 
</services> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="ServicesBehavior"> 
     <!--amith 13-05-2012--> 
     <serviceThrottling 
     maxConcurrentCalls="1000" 
     maxConcurrentSessions="1000" 
     maxConcurrentInstances="1000" 
     /> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="true" /> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 
<bindings> 
    <basicHttpBinding> 
    <binding name="basicHttpBinding" maxBufferSize="10000000" maxReceivedMessageSize="10000000"> 
     <readerQuotas maxStringContentLength="10000000" maxArrayLength="10000000"/> 
     <security mode="None"> 
     <transport clientCredentialType="None"/> 
     </security> 
    </binding> 

प्रबंधक के ग्राहकों:

 <endpoint name="endpoint1" contract="IDBConnectionContract" bindingConfiguration="basicHttpBinding" binding="basicHttpBinding" address="http://localhost:9010/DBConnectionService/DBService"></endpoint> 
    <endpoint name="endpoint2" contract="IGPPService" bindingConfiguration="basicHttpBinding" binding="basicHttpBinding" address="http://localhost:9095/GenericPPService/GenericPPService"></endpoint> 

डीबी कनेक्शन सेवा:

<service behaviorConfiguration="ServicesBehavior" name="Verifone.DBConnectionService.DBConnectionContracImpl"> 
    <host> 
     <baseAddresses> 
     <add baseAddress="http://localhost:9010/DBConnectionService/"/> 
     <add baseAddress="net.pipe://localhost/DBConnectionService/"/> 
     </baseAddresses> 
    </host> 
    <endpoint contract="Verifone.DBConnectionService.IDBConnectionContract" binding="basicHttpBinding" address="DBService"></endpoint> 

    <endpoint contract="Verifone.DBConnectionService.IDBConnectionContract" binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_Configuration" address="" name="pipeEndpoint"/> 
    </service> 

व्यापार तर्क सेवा के ग्राहक काफी प्रबंधक के तरह ही है।

सभी सेवाओं स्वयं की मेजबानी कर रहे हैं और मैं प्रबंधक के एक DBConnectionProxy वर्ग और व्यापार कोड है जो वे इस तरह सक्रिय कर दिया है:

DBConnectionContractClient _dbConnectionContractClient = null; 
     try 
     { 
      objDBConnectionContractClient = new DBConnectionContractClient(); 
      objDBConnectionContractClient.ExecuteStoredProcedure(input, out result); 
     } 
+0

आप किस प्रकार का इंस्टेंस और कॉन्सुरेंसी मोड का उपयोग कर रहे हैं? –

+0

ऐसा लगता है कि मैंने कोई मोड सेट नहीं किया है, इसलिए डिफ़ॉल्ट सेटिंग्स लागू होती हैं ... मुझे याद है कि मैं प्रति सत्र/एकाधिक जोड़ना चाहता था, लेकिन शायद इसे किसी भी तरह से याद किया, क्या मुझे इसे जोड़ना चाहिए? – Mithir

+4

persession/single डिफ़ॉल्ट है, concurency मोड एकाधिक –

उत्तर

4

परकॉल आप इन परिस्थितियों में इस इंस्टेंसिंग मोड पर विचार कर सकते हैं।

  • आपकी सेवा राज्यविहीन है

  • आपकी सेवा (
    सब पर या कोई नहीं) हल्के वजन प्रवर्तन कोड है।

  • यदि आपकी सेवा एकल धागा है।

कुछ अच्छे ट्यूटोरियल। ट्यूनिंग पर तीसरा लिंक देखें।

WCF Instancing, Concurrency, and Throttling – Part 1

WCF Instancing, Concurrency, and Throttling – Part 2

WCF Instancing, Concurrency, and Throttling – Part 3

+0

सुझाव के लिए धन्यवाद, मैंने दोनों की कोशिश की है लेकिन डीबी सेवा – Mithir

+0

पर भेजते समय अभी भी कतार प्राप्त करने का अनुरोध है, बस एक पहुंच शायद आप कैसे देखें परीक्षण करने के लिए ग्राहकों को सक्रिय कर रहे हैं। क्या आप संभवतः एक ही टेबल पर एक विशेष लॉक ले रहे हैं? – Paparazzi

+0

समस्या वास्तविक डीबी पर नहीं होती है लेकिन एक सेवा पर जो डीबी को सक्रिय करता है। तालिकाओं को भी एक मुद्दा होने से पहले अनुरोध उस सेवा में प्रवेश करने से पहले कतारबद्ध हैं। – Mithir

2

प्रति कॉल पसंद करेंगे। सत्र उपयोगी होगा यदि आप संसाधन गहन वस्तुओं को प्रारंभ करना चाहते हैं या प्रत्येक अनुरोध के लिए कुछ प्रीप्रोसेसिंग रूटिंग चला रहे हैं या राज्य को बनाए रखना चाहते हैं। सत्र आपको बेहतर प्रदर्शन दे सकता है लेकिन प्रति कॉल हमेशा बेहतर स्केल करता है। प्रति कॉल में आपको सहमति के बारे में चिंता करने की ज़रूरत नहीं है। जबकि पर्सन/एकाधिक के साथ नुकसान यह है कि आपको हमेशा अपने कोड में थ्रेड सुरक्षा के बारे में सोचना होगा।

+0

मुझे वास्तव में पता नहीं है कि क्या मामला है ... मैंने इसे सभी सेवाओं पर पर्कॉल या पर्सेशन मल्टीपल पर सेट किया है, लेकिन यह अभी भी कोई फर्क नहीं पड़ता है, मुख्य http wcf सेवा थ्रेड के बहुत से खुलती है, लेकिन केवल कुछ ही डीबी कनेक्शन सेवा ... – Mithir

+0

क्या यह संगत अनुरोध के साथ समस्या है, या यह कई उदाहरण खोलकर धीमा हो जाता है? –

+0

मैंने डब्ल्यूसीएफ सेवाओं की कुछ कॉन्फ़िगरेशन फाइलें जोड़ दी हैं, उम्मीद है कि यह थोड़ा – Mithir

1

बेस्ट विकल्प प्रति कॉल अगर आप सेवा स्थिति के बारे में परवाह नहीं है और अगर कोई बड़े कार्य करने आरंभीकरण पर किया जाता है, मुझे लगता है कि अपने मामले का वर्णन करता है मान होगा । उन डीएएल कॉलों को आजमाएं और हटाएं और देखें कि आपकी सेवा कैसा व्यवहार करती है, इस तरह आप यह पहचानने में सक्षम होंगे कि वह आपकी बोतल की गर्दन है या नहीं।

+0

यह वास्तव में आपके द्वारा सहायता की जा रही अन्य प्रश्न से जुड़ा हुआ है, धन्यवाद! :) – Mithir

+0

मैंने प्रश्न में कुछ विन्यास फाइलें जोड़ दी हैं। ओएस विंडोज सर्वर 2008 है। – Mithir

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