发出 HTTP 请求时避免网络限制

Avoid network throttling when making HTTP requests

我在发出 HTTP 网络请求时遇到了一个非常具体的问题。更具体地说,应用程序正在发出 24/7 请求并更新我的数据库 table。由于其他用户也在执行请求,我遇到了这样一种情况:当我使用并行 for 循环和并发包的组合来发出并行 Web 请求以加快处理速度时,其他用户的网站性能会大幅下降。在某些时候,当用户+应用程序发出请求时,网站变得非常缓慢且没有响应...... 所以现在我的问题如下:

如何限制它在特定时刻执行的网络请求的应用程序数量?

例如,如果有 10000 个可用端口,应用程序可以通过这些端口发出 Web 请求。我希望能够告诉应用程序一次使用 10/15 个线程来发出请求,同时不要降低用户的网站速度,这样就没有网络节流。

我读了几篇文章,有些人建议使用 semaphore slim,但我不知道如何将它与我的 Web 请求配对,如下所示:

  private string MakeHTTPWebRequest(string requestXML)
        {
            var request = (HttpWebRequest)WebRequest.Create("https://api.ebay.com/ws/api.dll");
            string GetItemTransactionXMLRequest = null;
            byte[] bytes = null;
            bytes = System.Text.Encoding.ASCII.GetBytes(requestXML);
            ServicePointManager.DefaultConnectionLimit = 9999;
            ServicePointManager.Expect100Continue = false;
            request.Method = "POST";
            request.ContentType = "application/xml";
            request.Accept = "application/xml";
            request.Proxy = null;

            Stream requestStream = request.GetRequestStream();
            requestStream.Write(bytes, 0, bytes.Length);
            requestStream.Close();
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Stream responseStream = response.GetResponseStream();
                    string responseStr = new StreamReader(responseStream).ReadToEnd();
                    responseStream.Flush();
                    responseStream.Close();
                    return responseStr;
                }
                return null;
            }
        }

我目前是这样做的:

Parallel.For(0,somelength,i=> List.Add(MakeHTTPWebRequest("Some xml request here")));

上面的方法给我带来了可怕的网络节流。我如何才能让应用程序知道它是否导致网络节流以减少调用次数或在用户发出请求时等待然后继续请求?

同时这引发了另一个问题,我如何将此网络请求中的超时设置为无限的 xxx 分钟,以便应用程序可以等到其他人完成他们的请求,以便它可以继续从 API...

有人可以帮我解决这个问题吗?

您每次发出 HTTP 请求时都会设置一些全局变量。我建议只设置一次。

I wanna be able to tell to application to use lets say 10/15 threads at a time to make the request

最快的解决方法是将 ParallelOptions 参数传递给 Parallel.For,将 MaxDegreeOfParallelism 设置为 10/15.

我还建议考虑使代码异步,因为这是一个 I/O-bound 操作。这就是您要使用 SemaphoreSlim 进行节流的地方。

How can I do this in a manner where application would know if it's causing network throttling to reduce number of calls

这是一个更难的问题。您必须测量您的响应时间并将它们提供给建立 "normal response time" 的例程,然后在响应时间开始变得太大时开始节流。这是假设您的应用程序像用户一样受到限制。