c# कॉल के दौरान_TransparantProxyStub_CrossContext फ़ंक्शन पर प्रतीक्षा करते समय WCF CPU को अधिकतम करता है



web-services soap (1)

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

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)
    {
    }

    ...

इस तरह मैं ग्राहक बनाऊँगा:

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;
    }
}

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

अद्यतन करें

उपहार के साथ थोड़ी अधिक जानकारी:

मैंने सी # वर्ग की तरह बनाया है:

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

आपको कॉल मैनेजर सिस्टम से सिस्को के एएक्सएल एपीआई के लिए डब्ल्यूएसडीएल डाउनलोड करना होगा। मैं एपीआई के 10.5 संस्करण का उपयोग कर रहा हूं। मेरा मानना ​​है कि एक प्रमुख मंदी XML प्रसंस्करण से संबंधित है। एपीआई के लिए डब्लूएसडीएल परिणामस्वरूप वर्गों के 538406 लाइनों को बनाते हुए बहुत बड़ा है!

अपडेट 2

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

अपडेट 3

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

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

4 अपडेट करें

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


मैंने अंत में इस समस्या को नीचे पकड़ा है। मूल कारण आपरेशनों की संख्या प्रतीत होता है 900+ कार्यों से उत्पन्न 12 से प्रत्येक ग्राहक ( इस प्रश्न के मार्गदर्शन के बाद) को उत्पन्न करने के बाद मैं लगभग शून्य के लिए अनुरोधों को बनाने पर खर्च किए गए प्रोसेसर के समय को कम करने में सक्षम था।

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

Wsdl का उपयोग करते हुए ग्राहक कोड उत्पन्न करें:

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

उप क्लाइंट में विभाजित करने के लिए उत्पन्न क्लाइंट फ़ाइल पर प्रक्रिया करें:

मैंने जेनरेट किए गए कोड को संसाधित करने के लिए इस स्क्रिप्ट को बनाया है। यह स्क्रिप्ट निम्न करता है:

  1. ServiceKnownType , FaultContract , और XmlInclude attributes को निकालें

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

  1. ऑपरेशन कॉन्ट्रैक्ट्स को अलग करें इंटरफ़ेस और इंटरफ़ेस को लागू करने वाले क्लाइंटबेस से तरीकों का निर्माण करें।

  2. 12 ऑपरेशंस और उनके संबंधित कार्यान्वयन के साथ प्रत्येक उप-क्लाइंट बनाएं

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

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

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

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

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





wsdl