2016-03-03 7 views
7

के दौरान _TransparantProxyStub_CrossContext फ़ंक्शन पर प्रतीक्षा करते समय CPU को अधिकतम करता है, मुझे डब्ल्यूसीएफ का उपयोग करते हुए सिस्को के एक्सएएल एसओएपी एपीआई में कॉल करते समय भारी CPU उपयोग मिल रहा है। मैं wsdl से उत्पन्न कक्षाओं का उपयोग कर एक सेवा मॉडल क्लाइंटबेस बनाकर शुरू करता हूं। मैं buichfered के रूप में basichttpbinding और ट्रांसफर्मोड का उपयोग कर रहा हूँ। कॉल निष्पादित करते समय, सीपीयू अधिकतम हो जाता है, और एक सीपीयू प्रोफाइल दिखाता है कि CPU% का 9 6% clr.dll से [email protected] पर है जिसे base.Channel.getPhone(request); जैसे कॉल के बाद बुलाया जाता है। अधिक सही ढंग से, कॉल CPU कोर को अधिकतम करता है जिस पर प्रक्रिया चल रही है।डब्ल्यूसीएफ कॉल

public class AxlClientFactory : IAxlClientFactory 
{ 
    private const string AxlEndpointUrlFormat = "https://{0}:8443/axl/"; 

    public AXLPortClient CreateClient(IUcClientSettings settings) 
    { 
     ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; 
     ServicePointManager.Expect100Continue = false;      

     var basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); 
     basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; 

     basicHttpBinding.MaxReceivedMessageSize = 20000000; 
     basicHttpBinding.MaxBufferSize = 20000000; 
     basicHttpBinding.MaxBufferPoolSize = 20000000; 

     basicHttpBinding.ReaderQuotas.MaxDepth = 32; 
     basicHttpBinding.ReaderQuotas.MaxArrayLength = 20000000; 
     basicHttpBinding.ReaderQuotas.MaxStringContentLength = 20000000; 

     basicHttpBinding.TransferMode = TransferMode.Buffered; 
     //basicHttpBinding.UseDefaultWebProxy = false; 

     var axlEndpointUrl = string.Format(AxlEndpointUrlFormat, settings.Server); 
     var endpointAddress = new EndpointAddress(axlEndpointUrl); 
     var axlClient = new AXLPortClient(basicHttpBinding, endpointAddress); 
     axlClient.ClientCredentials.UserName.UserName = settings.User; 
     axlClient.ClientCredentials.UserName.Password = settings.Password; 
     return axlClient; 
    } 
} 

AXL एपीआई के लिए उत्पन्न wsdl कोड बहुत बड़ी है:

यहाँ यह कैसे मैं ग्राहक बनाने है wsdl से ग्राहक सृष्टि का एक स्निप

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
public partial class AXLPortClient : System.ServiceModel.ClientBase<AxlNetClient.AXLPort>, AxlNetClient.AXLPort 
{ 

    public AXLPortClient() 
    { 
    } 

    public AXLPortClient(string endpointConfigurationName) : 
      base(endpointConfigurationName) 
    { 
    } 

    ... 

उत्पन्न है। शुरुआती और बाद की कॉल दोनों में सीपीयू समस्या है, हालांकि बाद में कॉल तेज हैं। क्या इस मुद्दे को डीबग करने के लिए मैं कुछ और कर सकता हूं? क्या इस उच्च CPU उपयोग को कम करने का कोई तरीका है? इनाम के साथ

अद्यतन

एक थोड़ा और अधिक जानकारी:

मैं बहुत की तरह सी # वर्गों बना लिया है:

svcutil AXLAPI.wsdl AXLEnums.xsd AXLSoap.xsd /t:code /l:C# /o:Client.cs /n:*,AxlNetClient 

आप सिस्को AXL एपीआई के लिए wsdl डाउनलोड करने के लिए है एक कॉल प्रबंधक प्रणाली से। मैं एपीआई के 10.5 संस्करण का उपयोग कर रहा हूँ। मेरा मानना ​​है कि एक बड़ी मंदी एक्सएमएल प्रसंस्करण से संबंधित है। एपीआई के लिए डब्लूएसडीएल परिणामस्वरूप कक्षाओं के साथ कोड की 538406 लाइनें बना रहा है!

अद्यतन 2

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

अद्यतन 3

मैं उत्पन्न ग्राहक वर्गों के लिए दो परिवर्तन किए हैं। सबसे पहले, मैंने सभी ऑपरेशन अनुबंधों से ServiceKnownTypeAttribute हटा दिया। दूसरा, मैंने कुछ धारावाहिक वर्गों से XmlIncludeAtribute को हटा दिया। इन दो परिवर्तनों ने जेनरेट किए गए क्लाइंट के फ़ाइल आकार को 50% से अधिक घटा दिया और परीक्षण समय पर एक छोटा प्रभाव पड़ा (70 के परीक्षण परिणाम पर लगभग 10s की कमी)।

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

अद्यतन 4

ऐसा लगता है कि आपरेशन की संख्या केंद्रीय समस्या है। मैं क्रिया द्वारा ऑपरेशन और इंटरफ़ेस परिभाषाओं को अलग करने में सक्षम था (उदा।हो जाता है, जोड़ता है, इत्यादि) अपने स्वयं के क्लाइंटबेस और इंटरफ़ेस में (उत्कृष्ट पाठ का उपयोग करके बहुत धीमी प्रक्रिया और रीशेर के रूप में रेगेक्स और कोडमेड बड़ी फ़ाइल को अभी भी 250K + लाइनों को संभाल नहीं सकता है)। लगभग 150 परिचालनों के साथ "गेट" क्लाइंट का परीक्षण पिछले 60 सेकंड के परिणाम की तुलना में गेटफोन के लिए 10 सेकंड निष्पादन के परिणामस्वरूप हुआ। यह अभी भी धीमी गति से है कि यह इस ऑपरेशन को फिडलर परिणामों में 2 सेकंड निष्पादन में तैयार करना चाहिए। समाधान शायद संचालन को अलग करने की कोशिश करके ऑपरेशन गिनती को और भी कम कर देगा। हालांकि, यह सभी लाइब्रेरी को तोड़ने की एक नई समस्या को जोड़ता है जो इस लाइब्रेरी को एक क्लाइंट के रूप में इस्तेमाल करता है।

+0

चूंकि यह एक निर्णायक प्रतिक्रिया नहीं है, इसलिए मैं एक समान अनुभव साझा करूंगा। मैं कई wsdl anss wsdl के साथ एक wcf बनाया था। मुझे उच्च सीपीयू उपयोग के साथ एक ही समस्या थी। मैं समस्या हल कर दूंगा, wcf परियोजना पर serialization के लिए असेंबली सेट। प्रोजेक्ट प्रॉपर्टीज में, सेक्शन बनाएं, आप "ऑनर सीरियलाइजेशन असेंबली" को "ऑन" पर सेट करने का प्रयास कर सकते हैं, और "एक्सएमएल डॉक्यूमेंटेशन" को "बिन \ रिलीज" या "बिन \ डीबग" फ़ोल्डर में भी सेट कर सकते हैं, इस पर निर्भर करता है कि आप कैसे हैं अपना समाधान बनाना अगर काम किया तो मुझे बताएं ताकि मैं एक उत्तर लिख सकूं और इस कामकाज के बारे में और अधिक पोस्ट कर सकूं। –

+0

मुझे इन दो विकल्पों को सेट करने से कोई प्रदर्शन वृद्धि नहीं हुई है। मैं रिलीज कॉन्फ़िगरेशन में यूनिट परीक्षण चला रहा था जिसमें सीरियलाइजेशन सेट ऑटो पर सेट किया गया था, जो इस अनुसार है (https://stackoverflow.com/questions/9187248/when-to-change-the-generate-serialization-assembly-value) का मतलब है क्रमबद्धता चालू है पहले से। एक्सएमएल दस्तावेज टिप्पणियों का अनुवाद इंटेलिजेंस afik में करने के लिए है, लेकिन मैंने वैसे भी कोशिश की। –

उत्तर

1

मैंने अंततः इस समस्या को कम कर दिया है। मूल कारण ऑपरेशन की संख्या प्रतीत होता है। जेनरेट किए गए क्लाइंट को 900+ ऑपरेशंस से 12 प्रत्येक तक विभाजित करने के बाद (this question से मार्गदर्शन के बाद) मैं लगभग शून्य तक अनुरोध उत्पन्न करने में व्यतीत प्रोसेसर समय को कम करने में सक्षम था।

यह वह जगह है सिस्को AXL wsdl से उत्पन्न सेवा ग्राहक के अनुकूलन के लिए अंतिम प्रक्रिया:

तो जैसे wsdl का उपयोग कर ग्राहक कोड जनरेट करें:

svcutil AXLAPI.wsdl AXLEnums.xsd AXLSoap.xsd /t:code /l:C# /o:Client.cs /n:*,AxlNetClient 

प्रक्रिया उत्पन्न ग्राहक फ़ाइल को तोड़ने के लिए उप ग्राहकों में:

मैंने जेनरेट कोड को संसाधित करने के लिए this script बनाया।

  1. ServiceKnownType, FaultContract, और XmlInclude गुण निकालें: यह स्क्रिप्ट निम्न है।

ये एक्सएमएल प्रोसेसिंग के लिए उपयोगी हैं, लेकिन जेनरेट क्लास जो मैं समझता हूं उससे गलत लगता है। उदाहरण के लिए सेवा अज्ञात, सभी परिचालनों के लिए समान है, भले ही कई ज्ञात प्रत्येक ऑपरेटर के लिए अद्वितीय हों। यह जेनरेट की गई फ़ाइल के कुल आकार को 500K + लाइनों से 250K + तक कम करता है, क्लाइंट तत्काल समय में मामूली प्रदर्शन वृद्धि के साथ।

  1. बाहर आपरेशन ठेके अलग clientbase कि इंटरफ़ेस को लागू से इंटरफेस और तरीकों के रूप में।

  2. 12 संचालन और उनके संबंधित कार्यान्वयन के साथ प्रत्येक उप-वर्ग बनाएँ।

इन उप-गुणकों में तीन मुख्य भाग हैं। पहला भाग मूल क्लाइंटबेस क्लाइंट का आंशिक वर्ग है। मैं चाहता हूं कि यह समाधान पिछड़ा संगत हो, इसलिए मेरे पास यहां विधियां हैं जो उपclient को संदर्भित करती हैं ताकि पुराने सुपर-क्लाइंट को कॉल किया जा सके, फिर भी नए उपclient को कॉल करके काम करते हैं। यदि किसी भी कार्यान्वित ऑपरेशन का संदर्भ दिया जाता है तो एक स्थिर पहुंच प्राप्तकर्ता उपclient शुरू करेगा। जब बंद या निरस्त कहा जाता है तब भी घटनाएं शामिल की जाती हैं ताकि उप-ग्राहक अभी भी इन परिचालनों को चला सकें।

उपclient के दूसरे और तीसरे भाग इंटरफ़ेस और उपclient वर्ग है जो 12 संचालन लागू करता है।

मैंने मूल जेनरेट क्लाइंट से इंटरफ़ेस और क्लाइंट विधियों को हटा दिया। मैंने क्लाइंट कन्स्ट्रक्टर को मूल क्लाइंट के लिए प्रतिस्थापित करने के लिए उप-प्रयोक्ताओं के लिए बाध्यकारी और एंडपॉइंट डेटा को बस स्टोर करने के लिए प्रतिस्थापित किया। ईवेंट बंद करने वालों को कॉल बंद करें और निरस्त कर दिया गया था कि प्रत्येक उपclient तत्काल होने पर सदस्यता लेगा।

आखिरकार, मैंने described here के समान कस्टम एंडपॉइंट व्यवहार के प्रमाणीकरण को स्थानांतरित कर दिया है। प्रमाणीकरण हेडर भेजने के लिए IClientMessageInspector का उपयोग तुरंत उस सर्वर पर एक राउंड ट्रिप कॉल में सहेजता है जहां डब्ल्यूसीएफ प्रमाणीकरण से पहले पहले एक अनाम अनुरोध भेजना पसंद करता है। यह मुझे सर्वर के आधार पर मोटे तौर पर 2 सेकंड की वृद्धि देता है।

कुल मिलाकर, मुझे 70 से 2.5 के बीच प्रदर्शन में वृद्धि हुई है।

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