ভিজুয়াল স্টুডিওর চেয়ে পাওয়ারশেল চলাকালীন এইচটিটিপি ক্লায়েন্ট সমকালীন আচরণটি আলাদা different


10

আমি বি 2 সি-তে ব্যবহারকারী তৈরি করতে এমএস গ্রাফ এপিআই ব্যবহার করে প্রিম-এডি AD থেকে আজুর এডি বি 2 সি-তে কয়েক মিলিয়ন ব্যবহারকারীকে স্থানান্তরিত করছি। আমি এই মাইগ্রেশনটি সম্পাদন করতে একটি নেট নেট 3.1 কনসোল অ্যাপ্লিকেশন লিখেছি। জিনিসগুলির গতি বাড়ানোর জন্য আমি গ্রাফ API এ একযোগে কল করছি। এটি দুর্দান্ত কাজ করছে - সাজানো।

উন্নয়নের সময় আমি ভিজ্যুয়াল স্টুডিও 2019 থেকে চলাকালীন গ্রহণযোগ্য পারফরম্যান্স পেয়েছি, তবে পরীক্ষার জন্য আমি পাওয়ারশেল 7.-এর কমান্ড লাইন থেকে চালাচ্ছি Pow পাওয়ারশেল থেকে এইচটিপিপ্লিয়েন্টে সমবর্তী কলগুলির অভিনয় খুব খারাপ। দেখা যাচ্ছে যে পাওয়ারশেল থেকে চলাকালীন এইচটিটিপিকল্যান্ট অনুমতি দিচ্ছে যে সমবর্তী কলগুলির সংখ্যার একটি সীমা রয়েছে, সুতরাং 40 থেকে 50 এর বেশি অনুরোধের সমবর্তী ব্যাচে কলগুলি স্ট্যাক আপ শুরু করে। মনে হচ্ছে 40 থেকে 50 সমবর্তী অনুরোধগুলি চলছে যখন বাকী অংশগুলি অবরুদ্ধ করে।

আমি অ্যাসিঙ্ক প্রোগ্রামিংয়ে সহায়তার সন্ধান করছি না। আমি ভিজ্যুয়াল স্টুডিও রান-টাইম আচরণ এবং পাওয়ারশেল কমান্ড লাইন রান-টাইম আচরণের মধ্যে পার্থক্য চিহ্নিত করার জন্য একটি উপায় খুঁজছি। ভিজ্যুয়াল স্টুডিওর সবুজ তীর বোতাম থেকে রিলিজ মোডে চলমান প্রত্যাশার সাথে আচরণ করে। কমান্ড লাইন থেকে চালানো না।

আমি async কল সহ একটি কার্য তালিকা পূরণ করি এবং তারপরে Task.WhenAll (কার্যাদি) এর জন্য অপেক্ষা করি। প্রতিটি কল 300 থেকে 400 মিলিসেকেন্ডের মধ্যে লাগে। ভিজ্যুয়াল স্টুডিও থেকে চলার সময় এটি প্রত্যাশার মতো কাজ করে। আমি 1000 কলগুলির একযোগে ব্যাচ করি এবং প্রতিটি স্বতন্ত্রভাবে প্রত্যাশিত সময়ের মধ্যে সম্পূর্ণ হয়। পুরো টাস্ক ব্লকটি দীর্ঘতম স্বতন্ত্র কলের চেয়ে কয়েক মিলিসেকেন্ড বেশি সময় নেয়।

আমি পাওয়ারশেল কমান্ড লাইন থেকে একই বিল্ড চালানোর সময় আচরণটি পরিবর্তিত হয়। প্রথম 40 থেকে 50 টি কলগুলি প্রত্যাশিত 300 থেকে 400 মিলিসেকেন্ড নেয় তবে তারপরে পৃথক কল সময় প্রতিটি 20 সেকেন্ড পর্যন্ত বৃদ্ধি পায়। আমি কলগুলি সিরিয়ালাইজ করা হচ্ছে বলে মনে করি, তাই অন্যরা অপেক্ষা করার সময় কেবল একবারে 40 থেকে 50 টি কার্যকর করা হয়।

কয়েক ঘন্টা পরীক্ষার এবং ত্রুটির পরে আমি এটিকে এইচটিপিপ্লেইন্টে সংকুচিত করতে সক্ষম হয়েছি। সমস্যাটি বিচ্ছিন্ন করার জন্য আমি কলটি উপহাস করেছিলাম HTTPClient.SendAsync এর সাথে একটি পদ্ধতি যা টাস্ক.ডেলা (300) করে এবং একটি মক ফলাফল প্রদান করে with এই ক্ষেত্রে কনসোল থেকে চলমান ভিজ্যুয়াল স্টুডিও থেকে চলমান হিসাবে একইরকম আচরণ করে।

আমি আইএইচটিপিপ্লায়েন্টফ্যাক্টরি ব্যবহার করছি এবং আমি এমনকি সার্ভিসপয়েন্ট ম্যানেজারে সংযোগের সীমাটি সামঞ্জস্য করার চেষ্টা করেছি।

এখানে আমার নিবন্ধকরণ কোড।

    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();

এখানে আমি কীভাবে এইচটিটিপিপ্লায়েন্টকে উপহাস করেছি।

        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 সমবর্তী অনুরোধগুলি ব্যবহার করে 10 কে বি 2 সি ব্যবহারকারীদের জন্য মেট্রিক রয়েছে। টিসিপি সংযোগ তৈরি হওয়ায় প্রথম 500 টি অনুরোধগুলি স্বাভাবিকের চেয়ে দীর্ঘ।

কনসোল রান মেট্রিকগুলির লিঙ্ক এখানে ।

ভিজ্যুয়াল স্টুডিও রান মেট্রিকগুলির লিঙ্ক এখানে ।

ভিএস রান মেট্রিক্সের ব্লক সময়গুলি আমি এই পোস্টে যা বলেছিলাম তার থেকে আলাদা কারণ কারণ পরীক্ষার রানগুলির জন্য যতটা সম্ভব সমস্যাযুক্ত কোডটি বিচ্ছিন্ন করার প্রয়াসে আমি সমস্ত সিঙ্ক্রোনাস ফাইল অ্যাক্সেস প্রক্রিয়াটির শেষের দিকে সরিয়ে নিয়েছি।

প্রকল্পটি নেট কোর 3.1 ব্যবহার করে সংকলিত হয়েছে। আমি ভিজ্যুয়াল স্টুডিও 2019 16.4.5 ব্যবহার করছি।


2
আপনি কি প্রথম ব্যাচের পরে নেটস্যাট ইউটিলিটির সাথে আপনার সংযোগের স্থিতি পর্যালোচনা করেছেন? এটি প্রথম কয়েকটি কাজ শেষ হওয়ার পরে কী চলছে তার কিছুটা অন্তর্দৃষ্টি সরবরাহ করতে পারে।
প্রণব নেগন্ধি

আপনি যদি এইভাবে সমাধান না করে থাকেন (এইচটিটিপি অনুরোধটি অ্যাসিঙ্ক করুন), আপনি সর্বদা প্রতিটি ব্যবহারকারীর জন্য কনক্রিয়েন্ট কিউয়েজ [অবজেক্ট] গ্রাহক / প্রযোজক সমান্তরালতার জন্য সিঙ্ক এইচটিটিপি কলগুলি ব্যবহার করতে পারেন। আমি সম্প্রতি পাওয়ারশেলের প্রায় 200 মিলিয়ন ফাইলের জন্য এটি করেছি।
thepip3r

1
@ thepip3r আমি আপনার প্রশংসা পুনরায় পড়েছি এবং এটি এটি এখন বুঝতে পেরেছি। আমি এটা মনে রাখব.
মার্ক লটার

1
না আমি বলছি না, আপনি যদি সি # এর পরিবর্তে পাওয়ারশেল যেতে চান: # eeholmes.com / blog / 2018 / 09 / 05/…
thepip3r

1
@ thepip3r শুধু স্টিফেন ক্লিয়ারি থেকে ব্লগ এন্ট্রি পড়ুন। আমার ভাল হওয়া উচিত।
মার্ক লটার

উত্তর:


3

দুটি বিষয় মাথায় আসে। বেশিরভাগ মাইক্রোসফ্ট পাওয়ারশেলটি সংস্করণ 1 এবং 2 তে রচনা করা হয়েছিল। সংস্করণ 1 এবং 2 এর রয়েছে সিস্টেম.থ্রেডিং T থ্রেড M এমটিএর অ্যাপার্টমেন্ট স্টেট। সংস্করণ 3 থেকে 5 এ অ্যাপার্টমেন্টের রাজ্যটি ডিফল্টরূপে এসটিএতে পরিবর্তিত হয়েছিল।

দ্বিতীয় চিন্তাটি হ'ল এগুলি শোনা যাচ্ছে যে তারা থ্রেডগুলি পরিচালনা করতে System.Threading.ThreadPool ব্যবহার করছে। আপনার থ্রেডপুলটি কত বড়?

যদি এগুলি সমস্যার সমাধান না হয় তবে তারা সিস্টেমের অধীনে খনন শুরু করে h

আমি যখন আপনার প্রশ্নটি পড়ি তখন আমি এই ব্লগটি ভেবেছিলাম। https://devblogs.microsoft.com/oldnewthing/20170623-00/?p=96455

একজন সহকর্মী একটি নমুনা প্রোগ্রামের সাহায্যে প্রদর্শিত হয়েছিল যা এক হাজার কাজের আইটেম তৈরি করে, যার প্রতিটি একটি কম্পিউটার কল সিমুলেট করে যা সম্পূর্ণ হতে 500 মিমি লাগে। প্রথম বিক্ষোভে, নেটওয়ার্ক কলগুলি সিঙ্ক্রোনাস কলগুলি অবরুদ্ধ করেছিল এবং প্রভাবটি আরও স্পষ্ট করার জন্য নমুনা প্রোগ্রামটি থ্রেড পুলটিকে দশটি থ্রেডে সীমাবদ্ধ করে। এই কনফিগারেশনের অধীনে প্রথম কয়েকটি কাজের আইটেমগুলি দ্রুত থ্রেডগুলিতে প্রেরণ করা হয়েছিল তবে নতুন কাজের আইটেমগুলিতে পরিষেবা দেওয়ার জন্য আর কোনও থ্রেড পাওয়া যায়নি, সুতরাং বাকী কাজ আইটেমগুলিকে একটি থ্রেডের জন্য আরও দীর্ঘতর অপেক্ষা করতে হয়েছিল এটি পরিষেবা উপলব্ধ। কাজের আইটেমটি শুরু হওয়ার গড় বিলম্বিতা দুই মিনিটেরও বেশি ছিল।

আপডেট 1: আমি স্টার্ট মেনু থেকে পাওয়ারশেল 7.0 চালিয়েছিলাম এবং থ্রেডের স্টেটটি এসটিএ ছিল। দুটি সংস্করণে থ্রেডের অবস্থা কি আলাদা?

PS C:\Program Files\PowerShell\7>  [System.Threading.Thread]::CurrentThread

ManagedThreadId    : 12
IsAlive            : True
IsBackground       : False
IsThreadPoolThread : False
Priority           : Normal
ThreadState        : Running
CurrentCulture     : en-US
CurrentUICulture   : en-US
ExecutionContext   : System.Threading.ExecutionContext
Name               : Pipeline Execution Thread
ApartmentState     : STA

আপডেট 2: আমি আরও ভাল উত্তর চাই তবে, কিছু না দাঁড়ানো পর্যন্ত আপনার দুটি পরিবেশের সাথে তুলনা করতে হবে।

PS C:\Windows\system32> [System.Net.ServicePointManager].GetProperties() | select name

Name                               
----                               
SecurityProtocol                   
MaxServicePoints                   
DefaultConnectionLimit             
MaxServicePointIdleTime            
UseNagleAlgorithm                  
Expect100Continue                  
EnableDnsRoundRobin                
DnsRefreshTimeout                  
CertificatePolicy                  
ServerCertificateValidationCallback
ReusePort                          
CheckCertificateRevocationList     
EncryptionPolicy            

আপডেট 3:

https://docs.microsoft.com/en-us/uwp/api/windows.web.http.httpclient

তদ্ব্যতীত, প্রতিটি এইচটিটিপিপ্লিনেন্ট তার নিজস্ব সংযোগ পুল ব্যবহার করে, অন্যান্য এইচটিটিপিপ্লিনেন্ট উদাহরণগুলির দ্বারা সম্পাদিত অনুরোধগুলি থেকে তার অনুরোধগুলি পৃথক করে।

যদি উইন্ডোজ.এইচবি.এইচটিপি নেমস্পেসে বিপুল পরিমাণে ডেটা (৫০ মেগাবাইট বা তার বেশি) ডাউনলোড করা কোনও অ্যাপ্লিকেশন যদি এইচটিপিপ্লিনেন্ট এবং সম্পর্কিত ক্লাস ব্যবহার করে তবে অ্যাপ্লিকেশনটিকে সেই ডাউনলোডগুলি স্ট্রিম করা উচিত এবং ডিফল্ট বাফারিং ব্যবহার করা উচিত নয়। যদি ডিফল্ট বাফারিং ব্যবহার করা হয় তবে ক্লায়েন্টের মেমরির ব্যবহার খুব বড় হবে, সম্ভাব্যতার ফলে কর্মক্ষমতা হ্রাস পাবে।

দুটি পরিবেশের সাথে কেবল তুলনা চালিয়ে যান এবং সমস্যাটি দাঁড়ানো উচিত

Add-Type -AssemblyName System.Net.Http
$client = New-Object -TypeName System.Net.Http.Httpclient
$client | format-list *

DefaultRequestHeaders        : {}
BaseAddress                  : 
Timeout                      : 00:01:40
MaxResponseContentBufferSize : 2147483647

পাওয়ারশেল .0.০ সিস্টেমে চলাকালীন h থ্রেডিং.ট্রেড.কন্টেনথ্রেড.গেট অ্যাপার্টমেন্ট স্টেট () প্রোগ্রামের মধ্যে থেকে এমটিএ ফিরিয়ে দেয় ainমেন ()
মার্ক লটার

ডিফল্ট মিনি থ্রেড পুলটি ছিল 12, আমি আমার ব্যাচের আকার (পরীক্ষার জন্য 500) ন্যূনতম পুলের আকার বাড়ানোর চেষ্টা করেছি। আচরণে এর কোনও প্রভাব ছিল না।
মার্ক লটার

উভয় পরিবেশে কতগুলি থ্রেড উত্পন্ন হয়?
হারুন

আমি ভাবছিলাম যে 'এইচটিপিপিপ্লিয়েন্ট' এর কতগুলি থ্রেড রয়েছে কারণ এটি সমস্ত কাজ করছে।
হারুন

আপনার উভয় সংস্করণে অ্যাপার্টমেন্টের অবস্থা কী?
হারুন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.