क्या हमें सभी अनुरोधों के लिए HttpClient का एक नया एकल उदाहरण बनाना चाहिए?


57

हाल ही में मैं asp.net राक्षसों से इस ब्लॉग पोस्ट पर आया जो HttpClientनिम्नलिखित तरीके से उपयोग करने के साथ मुद्दों के बारे में बात करता है :

using(var client = new HttpClient())
{
}

ब्लॉग पोस्ट के अनुसार, यदि हम HttpClientहर अनुरोध के बाद निपटान करते हैं तो यह टीसीपी कनेक्शन को खुला रख सकता है। इससे संभावित नुकसान हो सकता है System.Net.Sockets.SocketException

पोस्ट के अनुसार सही तरीका यह है कि एक एकल उदाहरण बनाया जाए HttpClientक्योंकि यह सॉकेट्स की बर्बादी को कम करने में मदद करता है।

पोस्ट से:

यदि हम HttpClient का एक भी उदाहरण साझा करते हैं तो हम सॉकेट्स के कचरे को पुन: उपयोग करके कम कर सकते हैं:

namespace ConsoleApplication
{
    public class Program
    {
        private static HttpClient Client = new HttpClient();
        public static void Main(string[] args)
        {
            Console.WriteLine("Starting connections");
            for(int i = 0; i<10; i++)
            {
                var result = Client.GetAsync("http://aspnetmonsters.com").Result;
                Console.WriteLine(result.StatusCode);
            }
            Console.WriteLine("Connections done");
            Console.ReadLine();
        }
    }
}

मैंने हमेशा इसका HttpClientउपयोग करने के बाद वस्तु का निपटान किया है क्योंकि मुझे लगा कि यह इसका उपयोग करने का सबसे अच्छा तरीका है। लेकिन यह ब्लॉग पोस्ट अब मुझे लगता है कि मैं यह सब गलत कर रहा था।

क्या हमें HttpClientसभी अनुरोधों के लिए एक नया एकल उदाहरण बनाना चाहिए ? क्या स्थैतिक उदाहरण का उपयोग करने के कोई नुकसान हैं?


क्या आपने अपने द्वारा उपयोग किए जा रहे तरीके के लिए किसी भी समस्या का सामना किया है?
whatsisname 16

हो सकता है कि जाँच इस जवाब है और यह भी इस
जॉन वू

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

3
मैंने इसे स्वयं करने की कोशिश नहीं की है (इसलिए इसे उत्तर के रूप में प्रदान नहीं किया गया है), लेकिन .NET कोर 2.1 के अनुसार Microsoft के अनुसार आप HttpClientFactory का उपयोग करने वाले हैं, जैसा कि डॉक्स.माइक्रोसॉफ्ट.com/en-us/dotnet/standard/
जोएरी सेब्रच्ट्स

(जैसा कि मेरे उत्तर में कहा गया है, बस इसे और अधिक दृश्यमान बनाना चाहते थे, इसलिए मैं एक छोटी टिप्पणी लिख रहा हूं।) स्टेटिक उदाहरण ठीक से tcp कनेक्शन को बंद करने के लिए हैंडशेक को संभालेंगे, जब आप Close()एक नया काम करते हैं या शुरू करते हैं Get()। यदि आप क्लाइंट का निपटान तब करते हैं, जब आप इसके साथ काम करते हैं, तो उस बंद हैंडशेक को संभालने के लिए कोई नहीं होगा और आपके पोर्ट सभी के लिए TIME_WAIT स्थिति होंगे।
म्लादेन बी।

जवाबों:


39

यह एक सम्मोहक ब्लॉग पोस्ट की तरह लगता है। हालाँकि, निर्णय लेने से पहले, मैं पहले उन्हीं परीक्षणों को चलाऊंगा जो ब्लॉग लेखक ने चलाए थे, लेकिन आपके कोड पर। मैं HttpClient और उसके व्यवहार के बारे में थोड़ा और जानने की कोशिश करूंगा।

यह पोस्ट बताता है:

एक HttpClient उदाहरण उस उदाहरण द्वारा निष्पादित सभी अनुरोधों पर लागू सेटिंग्स का एक संग्रह है। इसके अलावा, हर HttpClient इंस्टेंस अपने स्वयं के कनेक्शन पूल का उपयोग करता है, अन्य HttpClient इंस्टेंस द्वारा निष्पादित अनुरोधों से अपने अनुरोधों को अलग करता है।

तो क्या हो रहा है जब एक HttpClient साझा किया जाता है तो यह है कि कनेक्शन का पुन: उपयोग किया जा रहा है, जो ठीक है अगर आपको लगातार कनेक्शन की आवश्यकता नहीं है। एकमात्र तरीका है कि आप यह जानने के लिए जा रहे हैं कि क्या यह आपकी स्थिति के लिए मायने रखता है या नहीं, अपने स्वयं के प्रदर्शन परीक्षण चलाने के लिए।

यदि आप खोदते हैं, तो आपको कई अन्य संसाधन मिलेंगे, जो इस मुद्दे को संबोधित करते हैं (एक Microsoft सर्वोत्तम अभ्यास लेख सहित), इसलिए यह वैसे भी लागू करना एक अच्छा विचार है (कुछ सावधानियों के साथ)।

संदर्भ

आप Httpclient गलत का उपयोग कर रहे हैं और यह आपके सॉफ़्टवेयर
सिंगलटन HttpClient को अस्थिर कर रहा है ? इस गंभीर व्यवहार से सावधान रहें और यह कैसे तय करने के लिए
अनुचित प्रारंभ: प्रदर्शन अनुकूलन - माइक्रोसॉफ्ट पैटर्न और आचरण
संहिता समीक्षा पर पुन: प्रयोज्य HttpClient के एकल चरण
सिंगलटन HttpClient DNS परिवर्तन सम्मान नहीं करता है (CoreFX)
HttpClient प्रयोग करने के लिए जनरल सलाह


1
यह एक अच्छी व्यापक सूची है। यह मेरा सप्ताहांत पढ़ा गया है।
अंकित विजय

"यदि आप खोदते हैं, तो आपको कई अन्य संसाधन मिलेंगे जो इस मुद्दे को संबोधित करते हैं ..." आपको कहने का मतलब है कि टीसीपी कनेक्शन खुला मुद्दा?
अंकित विजय

संक्षिप्त उत्तर: एक स्थिर HttpClient का उपयोग करें । यदि आपको DNS परिवर्तनों (अपने वेब सर्वर या अन्य सर्वरों) का समर्थन करने की आवश्यकता है, तो आपको टाइमआउट सेटिंग्स के बारे में चिंता करने की आवश्यकता है।
जेस

3
यह एक वसीयतनामा है कि कैसे HttpClient को गड़बड़ किया गया है कि इसका उपयोग @AnkitVijay द्वारा टिप्पणी के रूप में एक "सप्ताहांत पढ़ा" है।
usr

@ DNS बदलावों के अलावा - अपने सभी क्लाइंट के ट्रैफ़िक को सिंगल सॉकेट के माध्यम से फेंकने से लोड बैलेंस में भी गड़बड़ होगी?
इयान

16

मुझे पार्टी के लिए देर हो रही है, लेकिन यहाँ इस मुश्किल विषय पर मेरी सीखने की यात्रा है।

1. हम HttpClient का पुन: उपयोग करने पर आधिकारिक अधिवक्ता कहां मिल सकते हैं?

मेरा मतलब है, अगर HttpClient का पुन: उपयोग करना उद्देश्य है और ऐसा करना महत्वपूर्ण है , तो ऐसे एडवोकेट को "उन्नत विषयों", "प्रदर्शन (विरोधी) पैटर्न" या अन्य ब्लॉग पोस्ट के बहुत सारे में छिपे होने के बजाय अपने स्वयं के एपीआई प्रलेखन में बेहतर दस्तावेज दिया जाता है। । अन्यथा किसी नए शिक्षार्थी को बहुत देर होने से पहले इसे कैसे जानना चाहिए?

अब (मई 2018) के अनुसार, "सी # httpclient" को googling करते हुए पहला खोज परिणाम MSDN पर इस API संदर्भ पृष्ठ की ओर इंगित करता है, जिसमें उस इरादे का उल्लेख बिल्कुल नहीं है। खैर, नौसिखिया के लिए सबक 1 यहाँ है, हमेशा MSDN मदद पृष्ठ शीर्षक के बाद "अन्य संस्करण" लिंक पर क्लिक करें, आपको संभवतः "वर्तमान संस्करण" के लिंक मिलेंगे। इस HttpClient मामले में, यह आपको नवीनतम दस्तावेज़ यहाँ लाएगा, जिसमें वह इरादा विवरण होगा

मुझे कई डेवलपर्स पर शक है जो इस विषय पर नए थे, उन्हें सही प्रलेखन पृष्ठ भी नहीं मिला, इसीलिए यह ज्ञान व्यापक रूप से फैला नहीं है, और लोग आश्चर्यचकित थे जब उन्हें बाद में पता चला , संभवतः एक कठिन तरीके से

2. (गलत?) का गर्भाधान using IDisposable

यह एक थोड़ा विषय से हटकर, लेकिन अभी भी उनका कहना है कि, यह आरोप लगा है कि उन aforementioned ब्लॉग पोस्ट में लोगों को देखने के एक संयोग नहीं है लायक है HttpClientके IDisposableइंटरफेस उन्हें इस्तेमाल करते हैं using (var client = new HttpClient()) {...}पैटर्न और फिर समस्या पैदा।

मेरा मानना ​​है कि एक अनिर्दिष्ट (गलत?) गर्भाधान के लिए नीचे आता है: "एक आईडीसोफोबिक ऑब्जेक्ट के अल्पकालिक होने की उम्मीद है"

जब हम इस शैली में कोड लिखते हैं तो यह निश्चित रूप से एक अल्पकालिक चीज की तरह दिखता है:

using (var foo = new SomeDisposableObject())
{
    ...
}

IDisposable पर आधिकारिक दस्तावेज कभी नहीं उल्लेख IDisposableवस्तुओं अल्पकालिक रहना होगा। परिभाषा के अनुसार, आईडीसॉरोप्लेट केवल एक तंत्र है जो आपको अप्रबंधित संसाधनों को जारी करने की अनुमति देता है। और कुछ नहीं। उस अर्थ में, आप अंततः निपटान को ट्रिगर करने के लिए तैयार हैं, लेकिन यह आपको अल्पकालिक फैशन में ऐसा करने की आवश्यकता नहीं है।

इसलिए यह आपकी नौकरी है कि जब आपकी वास्तविक वस्तु के जीवन चक्र की आवश्यकता के आधार पर निपटान को ट्रिगर करने के लिए ठीक से चुनना है। लंबे समय तक जीवित रहने के तरीके में आपको आईडीसॉपी का उपयोग करने से कोई रोक नहीं सकता है:

using System;
namespace HelloWorld
{
    class Hello
    {
        static void Main()
        {
            Console.WriteLine("Hello World!");

            using (var client = new HttpClient())
            {
                for (...) { ... }  // A really long loop

                // Or you may even somehow start a daemon here

            }

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}

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

3. क्या हमें HttpClient को एक स्थिर संपत्ति में रखना है, या एक सिंगलटन के रूप में भी डालना है?

पिछले अनुभाग की समझ के आधार पर, मुझे लगता है कि यहां उत्तर स्पष्ट हो गया है: "जरूरी नहीं"। यह वास्तव में इस बात पर निर्भर करता है कि आप अपने कोड को कैसे व्यवस्थित करते हैं, जब तक कि आप एक HttpClient का पुन: उपयोग नहीं करते हैं (आदर्श रूप से) इसे अंततः निपटाने।

प्रफुल्लित करने वाला, वर्तमान आधिकारिक दस्तावेज़ के रिमार्क्स अनुभाग में उदाहरण भी नहीं है, यह कड़ाई से सही है। यह एक "गुडकंट्रोलर" वर्ग को परिभाषित करता है, जिसमें स्थिर HttpClient गुण होता है जिसे निपटाया नहीं जाएगा; उदाहरण खंड में एक और उदाहरण क्या अवहेलना करता है : "निपटान को कॉल करने की आवश्यकता है ... इसलिए एप्लिकेशन संसाधनों को लीक नहीं करता है"।

और अंत में, सिंगलटन अपनी चुनौतियों के बिना नहीं है।

"कितने लोग सोचते हैं कि वैश्विक परिवर्तन एक अच्छा विचार है? कोई नहीं।

कितने लोग सोचते हैं कि सिंगलटन एक अच्छा विचार है? कुछ।

क्या देता है? सिंगलटन वैश्विक वैरिएबल का एक समूह हैं। "

- इस प्रेरक वार्ता से उद्धृत, "ग्लोबल स्टेट एंड सिंग्लेटन्स"

पुनश्च: SqlConnection

यह एक वर्तमान क्यू एंड ए के लिए अप्रासंगिक है, लेकिन यह शायद एक अच्छा-जानने वाला है। SqlConnection उपयोग पैटर्न अलग है। आपको SqlConnection का पुन: उपयोग करने की आवश्यकता नहीं है , क्योंकि यह इस तरह से अपने कनेक्शन पूल को बेहतर ढंग से संभाल लेगा।

अंतर उनके कार्यान्वयन दृष्टिकोण के कारण होता है। प्रत्येक HttpClient उदाहरण अपने स्वयं के कनेक्शन पूल ( यहाँ से उद्धृत ) का उपयोग करता है ; लेकिन SqlConnection अपने आप में एक केंद्रीय कनेक्शन पूल द्वारा किया जाता है, के अनुसार इस

और आपको अभी भी SqlConnection को निपटाना होगा, जैसा कि आपको HttpClient के लिए करना चाहिए।


14

मैंने कुछ परीक्षणों में स्थैतिक के साथ प्रदर्शन में सुधार देखा HttpClient। मैंने अपने परीक्षण के लिए नीचे दिए गए कोड का उपयोग किया:

namespace HttpClientTest
{
    using System;
    using System.Net.Http;

    class Program
    {
        private static readonly int _connections = 10;
        private static readonly HttpClient _httpClient = new HttpClient();

        private static void Main()
        {
            TestHttpClientWithStaticInstance();
            TestHttpClientWithUsing();
        }

        private static void TestHttpClientWithUsing()
        {
            try
            {
                for (var i = 0; i < _connections; i++)
                {
                    using (var httpClient = new HttpClient())
                    {
                        var result = httpClient.GetAsync(new Uri("http://bing.com")).Result;
                    }
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
        }

        private static void TestHttpClientWithStaticInstance()
        {
            try
            {
                for (var i = 0; i < _connections; i++)
                {
                    var result = _httpClient.GetAsync(new Uri("http://bing.com")).Result;
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
        }
    }
}

परीक्षण के लिए:

  • मैंने 10, 100, 1000 और 1000 कनेक्शन के साथ कोड चलाया।
  • औसत जानने के लिए प्रत्येक परीक्षा को 3 बार दौड़ाएं।
  • एक समय में एक विधि से निष्पादित

मैंने अनुरोध के HttpClientलिए इसे निपटाने के बजाय स्थैतिक का उपयोग करके 40% से 60% के बीच प्रदर्शन में सुधार पाया HttpClient। मैंने यहाँ ब्लॉग पोस्ट में प्रदर्शन परीक्षा परिणाम का विवरण रखा है


1

टीसीपी कनेक्शन को ठीक से बंद करने के लिए , हमें एक टीसीपी कनेक्शन खोलते समय एक फिन - फिन + एसीके - एसीके पैकेट अनुक्रम (बस SYN - SYN + ACK - ACK की तरह ) पूरा करना होगा। अगर हम सिर्फ एक .Close () विधि कहते हैं (आमतौर पर तब होता है जब एक HttpClient निपटाना होता है), और हम अपने करीबी अनुरोध (फिन + एसीके के साथ) की पुष्टि करने के लिए दूरस्थ पक्ष की प्रतीक्षा नहीं करते हैं, हम TIME-WAIT स्थिति पर समाप्त होते हैं स्थानीय टीसीपी पोर्ट, क्योंकि हमने अपने श्रोता (HttpClient) को निपटाया और हमें पोर्ट स्टेट को एक उचित बंद स्थिति में रीसेट करने का मौका नहीं मिला, जब एक बार रिमोट सहकर्मी हमें फिन + एसीके पैकेट भेजता है।

टीसीपी कनेक्शन को बंद करने का उचित तरीका यह होगा कि .Close () विधि को कॉल करें और हमारी तरफ आने के लिए दूसरी तरफ (फिन + एसीके) से करीबी घटना की प्रतीक्षा करें। तभी हम अपना अंतिम ACK भेज सकते हैं और HttpClient को डिस्पोज कर सकते हैं।

बस जोड़ने के लिए, "कनेक्शन: कीप-अलाइव" HTTP हेडर के कारण, यदि आप HTTP अनुरोधों को निभा रहे हैं, तो टीसीपी कनेक्शन को खुला रखना समझदारी है। इसके अलावा, आप HTTP शीर्ष लेख "कनेक्शन: बंद करें" को सेट करके, दूरस्थ पीयर को आपके लिए कनेक्शन बंद करने के लिए कह सकते हैं। इस प्रकार, आपके स्थानीय पोर्ट हमेशा TIME_WAIT स्थिति में होने के बजाय, ठीक से बंद हो जाएंगे।


1

यहाँ एक बुनियादी एपीआई क्लाइंट है जो कुशलता से HttpClient और HttpClientHandler का उपयोग करता है। जब आप अनुरोध करने के लिए एक नया HttpClient बनाते हैं तो बहुत अधिक ओवरहेड होता है। प्रत्येक अनुरोध के लिए HttpClient को फिर से न बनाएँ। जितना संभव हो HttpClient का पुन: उपयोग करें ...

using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
//You need to install package Newtonsoft.Json > https://www.nuget.org/packages/Newtonsoft.Json/
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;


public class MyApiClient : IDisposable
{
    private readonly TimeSpan _timeout;
    private HttpClient _httpClient;
    private HttpClientHandler _httpClientHandler;
    private readonly string _baseUrl;
    private const string ClientUserAgent = "my-api-client-v1";
    private const string MediaTypeJson = "application/json";

    public MyApiClient(string baseUrl, TimeSpan? timeout = null)
    {
        _baseUrl = NormalizeBaseUrl(baseUrl);
        _timeout = timeout ?? TimeSpan.FromSeconds(90);    
    }

    public async Task<string> PostAsync(string url, object input)
    {
        EnsureHttpClientCreated();

        using (var requestContent = new StringContent(ConvertToJsonString(input), Encoding.UTF8, MediaTypeJson))
        {
            using (var response = await _httpClient.PostAsync(url, requestContent))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
    }

    public async Task<TResult> PostAsync<TResult>(string url, object input) where TResult : class, new()
    {
        var strResponse = await PostAsync(url, input);

        return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });
    }

    public async Task<TResult> GetAsync<TResult>(string url) where TResult : class, new()
    {
        var strResponse = await GetAsync(url);

        return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });
    }

    public async Task<string> GetAsync(string url)
    {
        EnsureHttpClientCreated();

        using (var response = await _httpClient.GetAsync(url))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
    }

    public async Task<string> PutAsync(string url, object input)
    {
        return await PutAsync(url, new StringContent(JsonConvert.SerializeObject(input), Encoding.UTF8, MediaTypeJson));
    }

    public async Task<string> PutAsync(string url, HttpContent content)
    {
        EnsureHttpClientCreated();

        using (var response = await _httpClient.PutAsync(url, content))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
    }

    public async Task<string> DeleteAsync(string url)
    {
        EnsureHttpClientCreated();

        using (var response = await _httpClient.DeleteAsync(url))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
    }

    public void Dispose()
    {
        _httpClientHandler?.Dispose();
        _httpClient?.Dispose();
    }

    private void CreateHttpClient()
    {
        _httpClientHandler = new HttpClientHandler
        {
            AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
        };

        _httpClient = new HttpClient(_httpClientHandler, false)
        {
            Timeout = _timeout
        };

        _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(ClientUserAgent);

        if (!string.IsNullOrWhiteSpace(_baseUrl))
        {
            _httpClient.BaseAddress = new Uri(_baseUrl);
        }

        _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeJson));
    }

    private void EnsureHttpClientCreated()
    {
        if (_httpClient == null)
        {
            CreateHttpClient();
        }
    }

    private static string ConvertToJsonString(object obj)
    {
        if (obj == null)
        {
            return string.Empty;
        }

        return JsonConvert.SerializeObject(obj, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });
    }

    private static string NormalizeBaseUrl(string url)
    {
        return url.EndsWith("/") ? url : url + "/";
    }
}

उपयोग:

using (var client = new MyApiClient("http://localhost:8080"))
{
    var response = client.GetAsync("api/users/findByUsername?username=alper").Result;
    var userResponse = client.GetAsync<MyUser>("api/users/findByUsername?username=alper").Result;
}

-5

HttpClient वर्ग का उपयोग करने का कोई एक तरीका नहीं है। कुंजी आपके एप्लिकेशन को इस तरह से आर्किटेक्ट करना है जो इसके पर्यावरण और बाधाओं के लिए समझ में आता है।

जब आप सार्वजनिक एपीआई को उजागर करने की आवश्यकता होती है तो HTTP एक बेहतरीन प्रोटोकॉल है। यह हल्के वजन कम विलंबता आंतरिक सेवाओं के लिए भी प्रभावी रूप से इस्तेमाल किया जा सकता है - हालांकि आरपीसी संदेश कतार पैटर्न अक्सर आंतरिक सेवाओं के लिए एक बेहतर विकल्प है।

HTTP को अच्छी तरह से करने में बहुत जटिलता है।

निम्नलिखित को धयान मे रखते हुए:

  1. सॉकेट बनाना और टीसीपी कनेक्शन स्थापित करना नेटवर्क बैंडविड्थ और समय का उपयोग करता है।
  2. HTTP / 1.1 एक ही सॉकेट पर पाइपलाइन अनुरोधों का समर्थन करता है। पिछली प्रतिक्रियाओं की प्रतीक्षा करने की आवश्यकता के बिना, एक के बाद एक कई अनुरोध भेजना - यह संभवतः ब्लॉग पोस्ट द्वारा रिपोर्ट किए गए गति सुधार के लिए जिम्मेदार है।
  3. कैशिंग और लोड बैलेंसर - यदि आपके पास सर्वरों के सामने एक लोड बैलेंसर है, तो यह सुनिश्चित करने से आपके अनुरोधों का उचित कैश हेडर आपके सर्वर पर लोड को कम कर सकता है, और ग्राहकों को त्वरित प्रतिक्रियाएं मिल सकती हैं।
  4. कभी भी एक संसाधन का चुनाव न करें, आवधिक प्रतिक्रियाओं को वापस करने के लिए HTTP चंकिंग का उपयोग करें।

लेकिन सबसे ऊपर, परीक्षण, माप और पुष्टि। यदि यह डिज़ाइन के अनुसार व्यवहार नहीं कर रहा है, तो हम आपके अपेक्षित परिणाम प्राप्त करने के तरीके के बारे में विशिष्ट प्रश्नों के उत्तर दे सकते हैं।


4
यह वास्तव में कुछ भी पूछा जवाब नहीं है।
whatsisname

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

आपने HTTP का उपयोग करना है या नहीं, इसके बारे में थोड़ा सा लिखा है। ओपी ने पूछा कि किसी विशेष पुस्तकालय घटक का उपयोग कैसे करना सबसे अच्छा है।
whatsisname

1
@ मिचेलशॉ: HttpClientऔजार IDisposable। इसलिए यह उम्मीद नहीं की जा सकती है कि यह एक अल्पकालिक वस्तु है जो जानता है कि कैसे अपने आप को साफ करना है, एक usingबयान में लपेटने के लिए उपयुक्त जब भी आपको इसकी आवश्यकता होती है। दुर्भाग्य से, यह नहीं है कि यह वास्तव में कैसे काम करता है। ओपी से जुड़ा ब्लॉग पोस्ट स्पष्ट रूप से दर्शाता है कि ऐसे संसाधन हैं (विशेष रूप से, टीसीपी सॉकेट कनेक्शन) जो लंबे समय तक usingबयान के दायरे से बाहर रहते हैं और HttpClientवस्तु को संभवतः निपटारा कर दिया गया है।
रॉबर्ट हार्वे

1
मैं उस विचार प्रक्रिया को समझता हूं। यह सिर्फ अगर आप HTTP के बारे में आर्किटेक्चर के दृष्टिकोण से सोच रहे थे, और एक ही सेवा के लिए बहुत सारे अनुरोध करने का इरादा कर रहे थे - तो आप कैशिंग और पाइपलाइनिंग के बारे में सोच रहे होंगे, और फिर HttpClient को एक अल्पकालिक वस्तु बनाने के बारे में सोचा। बस गलत लग रहा है। इसी तरह, यदि आप विभिन्न सर्वरों के लिए अनुरोध कर रहे हैं और सॉकेट को लाइव रखने से कोई लाभ नहीं होगा, तो इसके उपयोग के बाद HttpClient ऑब्जेक्ट का निपटान करना समझ में आता है।
माइकल शॉ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.