簡體   English   中英

HttpWebRequest 非常慢!

[英]HttpWebRequest is extremely slow!

我正在使用開源庫連接到我的網絡服務器。 我擔心網絡服務器運行速度非常慢,然后我嘗試在 Ruby 中做一個簡單的測試,我得到了這些結果

Ruby 程序:10 個 HTTP GET 需要 2.11 秒

Ruby 程序:18.13 秒用於 100 個 HTTP GET

C# 庫:10 個 HTTP GET 需要 20.81 秒

C# 庫:100 個 HTTP GET 需要 36847.46 秒

我已經分析並發現問題出在這個函數上:

private HttpWebResponse GetRawResponse(HttpWebRequest request) {
  HttpWebResponse raw = null;
  try {
    raw = (HttpWebResponse)request.GetResponse(); //This line!
  }
  catch (WebException ex) {
    if (ex.Response is HttpWebResponse) {
      raw = ex.Response as HttpWebResponse;
    }
  }
  return raw;
}

標記的行本身需要超過 1 秒才能完成,而發出 1 個請求的 ruby​​ 程序需要 0.3 秒。 我也在 127.0.0.1 上做所有這些測試,所以網絡帶寬不是問題。

是什么導致了這種巨大的減速?

更新

查看更改后的基准測試結果。 我實際上用 10 個 GET 而不是 100 個進行了測試,我更新了結果。

我發現 Web 請求緩慢的罪魁禍首是代理屬性。 如果在調用 GetResponse 方法之前將此屬性設置為 null,則查詢將跳過代理自動檢測步驟:

request.Proxy = null;
using (var response = (HttpWebResponse)request.GetResponse())
{
}

在返回響應之前,代理自動檢測最多需要 7 秒進行查詢。 默認情況下為 HttpWebRequest 對象設置此屬性有點煩人。

這可能與您同時打開多個連接的事實有關。 默認情況下,最大打開 HTTP 連接數設置為兩個。 嘗試將其添加到您的 .config 文件中,看看它是否有幫助:

<system.net>
  .......
  <connectionManagement>
    <add address="*" maxconnection="20"/>
  </connectionManagement>
</system.net>

我在 VB.Net MVC 項目中遇到了類似的問題。
在我的電腦 (Windows 7) 本地,點擊頁面請求的時間不到 1 秒,但在服務器 (Windows Server 2008 R2) 上,每個頁面請求需要 20 多秒。

我嘗試了將代理設置為空的組合

  System.Net.WebRequest.DefaultWebProxy = Nothing
  request.Proxy = System.Net.WebRequest.DefaultWebProxy

並通過添加更改配置文件

 <system.net>
   .......
   <connectionManagement>
     <add address="*" maxconnection="20"/>
   </connectionManagement>
 </system.net>

這仍然沒有減少服務器上緩慢的頁面請求時間。 最后的解決方案是取消選中服務器本身 IE 選項中的“自動檢測設置”選項。 (在工具 -> Internet 選項下選擇連接選項卡。按 LAN 設置按鈕)

在我取消選中服務器上的此瀏覽器選項后,所有頁面請求時間立即從 20+ 秒下降到 1 秒以下。

我開始觀察到類似於該區域中的 OP 的減速,當增加 MaxConnections 時,速度會有所改善。

ServicePointManager.DefaultConnectionLimit = 4;

但是在構建了這個數量的 WebRequest 之后,延遲又回來了。

就我而言,問題在於我正在調用 POST 並且不關心響應,因此沒有接聽或對它做任何事情。 不幸的是,這讓 WebRequest 一直浮動,直到它們超時。

解決方法是拿起 Response 並關閉它。

WebRequest webRequest = WebRequest.Create(sURL);
webRequest.Method = "POST";
webRequest.ContentLength = byteDataGZ.Length;
webRequest.Proxy = null;
using (var requestStream = webRequest.GetRequestStream())
{
    requestStream.WriteTimeout = 500;
    requestStream.Write(byteDataGZ, 0, byteDataGZ.Length);
    requestStream.Close();
}
// Get the response so that we don't leave this request hanging around
WebResponse response = webRequest.GetResponse();
response.Close();

使用localhost以外的計算機,然后使用WireShark查看網絡上真正發生了什么。

就像其他人所說的那樣,它可以是很多東西。 在 TCP 級別上查看事物應該會給出清晰的畫面。

我不知道我到底是如何達到這個解決方法的,我還沒有時間做一些研究,所以這取決於你們。 有一個參數,我像這樣使用它(在我的類的構造函數中,在實例化 HTTPWebRequest 對象之前):

System.Net.ServicePointManager.Expect100Continue = false;

我不知道究竟是為什么,但現在我的電話看起來更快了。

我知道這是一些舊線程,但是我因 HttpWebRequest 緩慢而迷失了一整天,嘗試了所有提供的解決方案,但都沒有運氣。 對任何地址的每次請求都超過一分鍾。

最終,問題出在我的防病毒防火牆 (Eset) 上 我在交互模式下使用防火牆,但Eset 以某種方式完全關閉 這導致請求永遠持續。 開啟 Eset並執行請求后,顯示提示防火牆消息,確認后,請求執行不到一秒

對我來說,使用HttpWebRequest在本地調用 API 平均需要 40 毫秒,在服務器上調用 API 平均需要 270 毫秒。 但是在兩種環境中通過 Postman 調用它們平均需要 40 毫秒。 該線程中的任何解決方案都沒有對我產生任何影響。

然后我發現這篇文章提到了 Nagle 算法:

Nagle 算法通過減少通過網絡發送的數據包數量來提高網絡效率。 當少量數據寫入網絡時,它通過在客戶端設置最多 200 毫秒延遲來實現這一點。 延遲是可能寫入的其他數據的等待期。 新數據被添加到同一個數據包中。

ServicePoint.UseNagleAlgorithm設置為false是我需要的魔法,它產生了巨大的差異,服務器上的性能現在幾乎與本地相同。

var webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ServicePoint.Expect100Continue = false;
webRequest.ServicePoint.UseNagleAlgorithm = false; // <<<this is the important bit

請注意,這對我來說適用於少量數據,但是如果您的請求涉及大量數據,那么根據請求的大小/響應的預期大小,可能值得將此標志設為條件。

我嘗試了這里描述的所有解決方案,但沒有成功,電話大約需要 5 分鍾。

問題是什么:我需要相同的會話和顯然相同的 cookie(在同一台服務器上發出的請求),所以我將 cookie 從 Request.Cookies 重新創建到 WebRequest.CookieContainer 響應時間約為 5 分鍾。

我的解決方法:注釋掉cookie相關的代碼,bam! 通話時間不到一秒鍾。

這對我有用:

<configuration>
  <system.net>
    <defaultProxy enabled="false"/>
  </system.net>
</configuration>

信用程序第一次啟動時緩慢的 HTTPWebRequest

對我來說,問題是我安裝了 LogMeIn Hamachi——具有諷刺意味的是遠程調試相同的程序,然后開始表現出這種極端緩慢。

僅供參考,禁用 Hamachi 網絡適配器是不夠的,因為它的 Windows 服務似乎重新啟用了適配器。

此外,重新連接到我的 Hamachi 網絡並沒有解決問題。 僅禁用適配器(通過禁用 LogMeIn Hamachi Windows 服務)或者,大概是卸載 Hamachi,為我解決了問題。

是否可以通過特定的網絡適配器要求HttpWebRequest出去?

在我的情況下,將AspxAutoDetectCookieSupport=1添加到代碼中,問題就解決了

Uri target = new Uri("http://payroll");

string responseContent;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(target);

request.CookieContainer = new CookieContainer();         
request.CookieContainer.Add(new Cookie("AspxAutoDetectCookieSupport", "1") { Domain = target.Host });

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    using (Stream responseStream = response.GetResponseStream())
    {
        using (StreamReader sr = new StreamReader(responseStream))
            responseContent = sr.ReadToEnd();
    }
}

我們在工作中遇到了類似的問題,我們有兩個 REST API 在本地相互通信。 在我們的例子中,所有HttpWebRequest花費了超過 2 秒的時間,即使請求 url 是http://localhost:5000/whatever也很慢。

但是,在使用 Wireshark 調查此問題時,我們發現了這一點:

線鯊

結果發現框架首先嘗試建立到本地主機的 IPv6 連接,但是由於我們的服務正在偵聽0.0.0.0 (IPv4) 連接嘗試失敗,並且在 500 毫秒超時后重試,直到嘗試失敗 4 次(4 * 500 毫秒) = 2 秒)它最終放棄並使用 IPv4 作為后備(顯然幾乎立即成功)。

我們的解決方案是將請求 URI 更改為http://127.0.0.1/5000/whatever (或者還偵聽我們認為對於本地回調不必要的 IPv6)。

通過 httpwebrequest 創建到 api 的會話時,我遇到了 15 秒左右的延遲。 延遲是在等待 getrequeststream() 。 在尋找答案后,我找到了這篇文章,解決方案只是更改有關 ssl 的本地 Windows 策略:

https://www.generacodice.com/en/articolo/1296839/httpwebrequest-15-second-delay-performance-issue

我們在網絡應用程序上遇到了同樣的問題。 我們等待響應 5 秒。 當我們將 IIS 上的 applicationPool 上的用戶更改為 networkService 時,響應開始到達不到 1 秒

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM