gpt4 book ai didi

.net - .NET应用程序中超过3000个线程的瓶颈(HttpWebReqsuest.BeginGetResponse)

转载 作者:行者123 更新时间:2023-12-03 13:19:38 26 4
gpt4 key购买 nike

因此,我正在创建一个使用HTTP API来获取约50,000个帐户中每个帐户状态的应用程序。该代码循环遍历每个帐户,并为其发送HTTP请求。当我根据某些条件收到http请求的响应时,将创建一个新线程来管理该帐户。

现在正常情况下,我可以很容易地每秒发送大约1K个请求,但是一旦我碰到了大约3,100个 Activity 线程,http请求循环就会开始变慢并冻结到每秒仅大约1个请求。然后它突然跳回到每秒3k,然后冻结了几秒钟...等等。重要的是,它似乎并没有逐渐退化的趋势。它发生得非常突然。

显然,某个地方存在瓶颈,但是我不确定在哪里。我确保将TCP参数(可用端口的最大数量)设置为高限制。我将servicepoint.defaultconnection限制设置为int.maxvalue。

我的CPU是具有专用1Gbps的4核(带有HT的8线程)。我正在考虑迁移到更大的计算机(32核2x CPU)。但是我不确定它是否会带来任何好处。我想知道是否有人意识到我可能遇到的其他瓶颈。

我什至没有用光我所有的带宽或内存,我知道那不是问题。

这大致就是我的代码的样子

Sub Main()
While 1
For each account As Account in GetAccountsFromDatabase()'~50K Accounts
dim request = HttpWebRequest.Create("http://api.com?id=" & account.name)
request.BeginGetResponse(New AsyncCallback(AddressOf HandleResponse), request)
RequestsSent += 1
Console.Writeline("Request")

'After ~3000 active threads in the process, this loop begins freezing/slowing down.

if RequestsSent > 5000 then 'Limit
Thread.Sleep(5000)
RequestsSent = 0
end if

Next
End While
End Sub

Sub HandleResponse(ByVal asynchronousResult As IAsyncResult)
Dim webRequest As HttpWebRequest = DirectCast(asynchronousResult.AsyncState, HttpWebRequest)
Dim webResponse As HttpWebResponse = webRequest.EndGetResponse(asynchronousResult)
Dim stream As New StreamReader(webResponse.GetResponseStream())
Dim response = stream.ReadToEnd

if response.contains("somestuff") then
dim t As New Thread(AddressOf ProcessAccount)
t.Start(account)
end if

End Sub

Sub ProcessAccount(acc As Account)
'Process the account. Involves some other loops, http requests...etc
End Sub

最佳答案

好吧,您正在异步启动请求,但是一旦BeginGetResponse完成,您就会同步处理该请求。这最终可能会消耗池中的许多线程。也许您的配置中的池限制为3000个线程左右。

您需要扔掉它。一旦进入数百个线程,并且肯定进入了1000个线程,就需要切换到异步非阻塞IO。使用await,这变得非常容易。

使流读取部分异步(ReadToEnd)。可能应该删除所有代码,并用var str = await new HttpClient().GetAsync(url);(C#)替换。

接下来,运行50,000(!)个线程是不明智的。仅此一项就将为您设置50 GB(!)的堆栈内存。操作系统也开始安排我在测试中发现的所有这些线程有麻烦。例如,尽管鼠标驱动程序具有很高的优先级,但鼠标仍会停止移动几秒钟。显然,内核团队并不在乎这种情况。

可能应该以给定的并行度处理帐户。例如,仅同时处理100个。

如果出于某种原因需要同时处理它们,那么ProcessAccount也必须是异步的。别无退路。

关于.net - .NET应用程序中超过3000个线程的瓶颈(HttpWebReqsuest.BeginGetResponse),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30426701/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com