मैं बी 2 सी में उपयोगकर्ताओं को बनाने के लिए एमएस ग्राफ़ एपीआई का उपयोग करके एज़ एडी एडी बी 2 सी पर लाखों से अधिक उपयोगकर्ताओं को माइग्रेट कर रहा हूं। मैंने इस माइग्रेशन को करने के लिए एक .Net कोर 3.1 कंसोल एप्लिकेशन लिखा है। चीजों को गति देने के लिए मैं ग्राफ एपीआई पर समवर्ती कॉल कर रहा हूं। यह बहुत अच्छा काम कर रहा है।
विकास के दौरान मैंने विजुअल स्टूडियो 2019 से चलने के दौरान स्वीकार्य प्रदर्शन का अनुभव किया, लेकिन टेस्ट के लिए मैं पॉवरशेल 7 में कमांड लाइन से चल रहा हूं। पॉवर्सशेल से HttpClient के समवर्ती कॉल का प्रदर्शन बहुत खराब है। ऐसा प्रतीत होता है कि पॉवरशेल से चलते समय HttpClient को अनुमति देने वाले समवर्ती कॉल की संख्या की सीमा होती है, इसलिए समवर्ती बैचों में 40 से 50 से अधिक अनुरोधों को कॉल करना शुरू हो जाता है। ऐसा लगता है कि बाकी को अवरुद्ध करते हुए 40 से 50 समवर्ती अनुरोध चल रहे हैं।
मैं async प्रोग्रामिंग के साथ सहायता के लिए नहीं देख रहा हूँ। मैं विजुअल स्टूडियो रन-टाइम व्यवहार और पॉवर्सशेल कमांड लाइन रन-टाइम व्यवहार के बीच अंतर को शूट करने में परेशानी का एक तरीका ढूंढ रहा हूं। विजुअल स्टूडियो के ग्रीन एरो बटन से रिलीज़ मोड में चल रहा है जैसा कि अपेक्षित है। कमांड लाइन से नहीं चल रहा है।
मैं async कॉल के साथ एक कार्य सूची भरता हूं और फिर Task.WhenAll (कार्य) का इंतजार करता हूं। प्रत्येक कॉल में 300 से 400 मिली सेकेंड लगते हैं। जब Visual Studio से चल रहा है, यह अपेक्षित रूप से काम करता है। मैं 1000 कॉल के समवर्ती बैच बनाता हूं और प्रत्येक व्यक्तिगत रूप से अपेक्षित समय के भीतर पूरा होता है। पूरे टास्क ब्लॉक में सबसे लंबी व्यक्तिगत कॉल की तुलना में सिर्फ कुछ मिलीसेकंड अधिक समय लगता है।
जब मैं Powershell कमांड लाइन से एक ही बिल्ड चलाता हूं तो व्यवहार बदल जाता है। पहले 40 से 50 कॉल अपेक्षित 300 से 400 मिली सेकेंड लगते हैं लेकिन फिर व्यक्तिगत कॉल समय प्रत्येक 20 सेकंड तक बढ़ता है। मुझे लगता है कि कॉल धारावाहिक हो रहे हैं, इसलिए केवल 40 से 50 को एक बार में निष्पादित किया जा रहा है जबकि अन्य प्रतीक्षा कर रहे हैं।
घंटों परीक्षण और त्रुटि के बाद मैं इसे HttpClient तक सीमित करने में सक्षम था। समस्या को अलग करने के लिए मैंने HttpClient.SendAsync को कॉल करने के लिए एक विधि का उपयोग किया, जो कार्य करता है। Task.Delay (300) और एक नकली परिणाम देता है। इस स्थिति में कंसोल से चल रहा है विजुअल स्टूडियो से चलने के लिए व्यावहारिक रूप से व्यवहार करता है।
मैं IHttpClientFactory का उपयोग कर रहा हूं और मैंने ServicePointManager पर कनेक्शन सीमा को समायोजित करने की भी कोशिश की है।
यहां मेरा पंजीकरण कोड है।
public static IServiceCollection RegisterHttpClient(this IServiceCollection services, int batchSize)
{
ServicePointManager.DefaultConnectionLimit = batchSize;
ServicePointManager.MaxServicePoints = batchSize;
ServicePointManager.SetTcpKeepAlive(true, 1000, 5000);
services.AddHttpClient(MSGraphRequestManager.HttpClientName, c =>
{
c.Timeout = TimeSpan.FromSeconds(360);
c.DefaultRequestHeaders.Add("User-Agent", "xxxxxxxxxxxx");
})
.ConfigurePrimaryHttpMessageHandler(() => new DefaultHttpClientHandler(batchSize));
return services;
}
यहाँ DefaultHttpClientHandler है।
internal class DefaultHttpClientHandler : HttpClientHandler
{
public DefaultHttpClientHandler(int maxConnections)
{
this.MaxConnectionsPerServer = maxConnections;
this.UseProxy = false;
this.AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate;
}
}
यहां वह कोड है जो कार्यों को सेट करता है।
var timer = Stopwatch.StartNew();
var tasks = new Task<(UpsertUserResult, TimeSpan)>[users.Length];
for (var i = 0; i < users.Length; ++i)
{
tasks[i] = this.CreateUserAsync(users[i]);
}
var results = await Task.WhenAll(tasks);
timer.Stop();
यहां बताया गया है कि कैसे मैंने HttpClient का मजाक उड़ाया।
var httpClient = this.httpClientFactory.CreateClient(HttpClientName);
#if use_http
using var response = await httpClient.SendAsync(request);
#else
await Task.Delay(300);
var graphUser = new User { Id = "mockid" };
using var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(JsonConvert.SerializeObject(graphUser)) };
#endif
var responseContent = await response.Content.ReadAsStringAsync();
500 समवर्ती अनुरोधों का उपयोग करके ग्राफएपीआई के माध्यम से बनाए गए 10k बी 2 सी उपयोगकर्ताओं के लिए यहां मैट्रिक्स दिए गए हैं। पहले 500 अनुरोध सामान्य से अधिक हैं क्योंकि टीसीपी कनेक्शन बनाए जा रहे हैं।
यहाँ कंसोल रन मेट्रिक्स का लिंक दिया गया है ।
यहां विजुअल स्टूडियो रन मेट्रिक्स का लिंक दिया गया है ।
वीएस रन मेट्रिक्स में ब्लॉक का समय इस पोस्ट में मेरे द्वारा कही गई बातों से अलग है क्योंकि मैंने समस्याग्रस्त कोड को परीक्षण रन के लिए जितना संभव हो सके उतना अलग करने के प्रयास में प्रक्रिया के अंत तक सभी सिंक्रोनस फ़ाइल का उपयोग किया।
यह परियोजना .Net Core 3.1 का उपयोग करके संकलित की गई है। मैं विजुअल स्टूडियो 2019 16.4.5 का उपयोग कर रहा हूं।