併發訪問超時的問題可能性 引用

2022-03-12 14:09:24 字數 4714 閱讀 8282

用c#模擬網頁登陸,其中去請求幾個頁面,會發起對應的http的請求request,其中keepalive設定為true,提交請求後,然後會有對應的response:

之前的多次除錯,一直都是可以正常獲得對應的response,然後讀取html頁面的。

但是後來幾次的除錯,在沒有改變**的前提下,結果getresponse卻始終會超時死掉。

【解決過程】

1.預設request的timeout是1000000毫秒=100秒,都會超時,手動改為10秒,因此就更容易超時了,無法解決問題。

2.將http的request的keepalive設定為false,問題依舊。

3.去參考:c# request.getresponse();超時問題的解決,和httpwebrequest多執行緒效能問題,請求超時的錯誤,

去把前面共4次的httprequest,每次都增加對應的:

resp = null;

。。。

if (resp != null)

if (req != null)

結果還是沒解決問題。

4. 同樣參考:httpwebrequest多執行緒效能問題,請求超時的錯誤,

去嘗試關於defaultconnectionlimit的設定,改為為10:

system.net.servicepointmanager.defaultconnectionlimit = 10;

問題依舊。

5.又去測試了下,關於response.close()

也是沒解決問題。

6. 最後無意間,索性不抱希望的,再次defaultconnectionlimit設定為更大的值50:

system.net.servicepointmanager.defaultconnectionlimit = 50;

試了試,結果就解決超時的問題了。

然後才搞懂原因。

之前預設設定為2,後來改為10,都沒有解決問題的原因在於,當前有很多個http的連線,沒有被關閉掉,

而這些keepalive的連線,都是

由於**中,對於前面多個request。其都是keepalive為true,以及多個response也沒有close,

而之前除錯了很多次了,所以,此時已經存在了很多個alive的http連線了,已經超過了10個了,所以前面設定了defaultconnectionlimit 為10,也還是沒用的。

而改為50,才夠用。

【總結】

此處getresponse超過的原因是,當前存在太多數目的alive的http連線(大於10個),所以再次提交同樣的http的request,再去getresponse,就會超時死掉。

解決辦法就是,把defaultconnectionlimit 設定為乙個比較大一點的數值,此數值保證大於你當前已經存在的alive的http連線數即可。

【經驗總結】

以後寫http的request**,如果不是必須的要keepalive的,那麼就要設定keepalive為false:

req.keepalive = false;

以及做對應的收尾動作:

if (resp != null)

if (req != null)

【後記 2012-03-01】

又偶爾遇到一次,defaultconnectionlimit已經是200了,足夠大了,但是getresponse和getrequeststream,還是會超時死掉的問題,具體是什麼原因導致的還不是很清楚,但是經過折騰,參考:

在:req = (httpwebrequest)webrequest.create(constskydriveurl);

之前,新增一句垃圾**:

system.gc.collect();

然後就解決了getresponse的超時問題,並且後面的getrequeststream也同時可以正常工作,不超時了。

所以,看起來像是當前系統由於除錯多次,並且httpwebrequest和httpwebresponse都是沒有正常去close的,可能會殘

【總結】

對於getresponse或getrequeststream超時死掉的原因,可能是:

1.defaultconnectionlimit是預設的2,而當前的http的connection用完了,導致後續的getresponse或getrequeststream超時死掉

==>> 預設系統只支援同時存在2個http的connection

==>>

使用httpwebrequest之後如果沒有close,則會占用1個http的connection,所以如果超過2次使用

httpwebrequest而沒有close,那麼就用完系統的http的connection,之後再去使用

httpwebrequest,getresponse就會死掉

解決辦法:

辦法1:

每次使用完httpwebrequest,使用?1

2req.close();

req=null;

去關閉對應的http connection

最好對應的httpwebresponse也要close:?1

2resp.close();

resp =null;

方法2:

修改defaultconnectionlimit的值,改為足夠大,比如:?1

system.net.servicepointmanager.defaultconnectionlimit = 200;

2.系統中http相關的資源沒有正確釋放,導致後續getresponse或getrequeststream超時死掉

就像我此處遇到的,可能是之前呼叫http相關函式,沒有正確完全釋放資源,導致雖然defaultconnectionlimit給了足夠大,但

是還是會死掉,此時在http請求**之前去做一次垃圾**,則後續http的getresponse或getrequeststream就正常了,就不

會超時死掉了。?1

3.http的get請求時,不要手動設定contentlength的值

這個是參考這裡:httpwebrequest.getresponse() hangs the second time it is called而記錄於此的,也許有人是此原因,所以可供參考一下。

即http的get請求,不要新增類似如下的**:?1

不要去手動修改對應的contentlength的值,c#的http相關庫函式,會自動幫你計算的。

注:post方法中,的確是要手動填充資料和算出資料大小,然後手動給contentlength賦值的。

4.其他可能的一些原因

(1)關於keepalive的問題

如果http的請求,是設定了keepalive=true的話,那麼對應的http的connection會和伺服器保持連線的。

所以如果上述辦法都不能解決超時的問題,可以嘗試將keepalive設定為false試試,看看能否解決。

(2)關於sleep

有些人好像是通過在http請求前,加了對應的sleep,結果解決了此問題。需要的人,也可以試試。

(3)httpwebrequest的timeout

一般來說,既然超時了,往往是由於錯誤使用函式或者網路有問題導致的,所以實際上此處對於有些人去把httpwebrequest的timeout的值改的更大,往往都是沒用的。

只不過,萬一是由於網路響應慢而導致超時,那麼倒是可以嘗試,將httpwebrequest的timeout的值改為更大。

(其中httpwebrequest的timeout預設的值是100,000 milliseconds ==100 seconds)?1

req.timeout = 5 * 60 * 1000;// 5 minutes

附加**參考:

程式對話的可能性

假設程式a和程式b都採用同一種語言。這種語言支援用 片段來打補丁。來達到a,b不斷修改對方的程式的目的。a,b通過不斷的學習網路上的動態資源,達到不斷進化的目的。a,b可繁殖。通過提取自己的特徵碼來作為自己的dna,結合對方的dna,利用仿dna配對的演算法,可能還要進行變異 即進行隨機變換 不是固...

Decode Ways 不同的解碼可能性

a 1 b 2 z 26 given an encoded message containing digits,determine the total number of ways to decode it.for example,given encoded message 12 it could ...

erlang 程序獨佔的可能性

erlang 程序獨佔的可能性 erlang 的程序排程靠的是reduction,reduction的呼叫一般是在某乙個原子或者基礎指令呼叫完後才會呼叫,如果減少至0,則程序切換。所以程序並不是在任意指令下切換。那也就是說如果有某個命令沒有呼叫到reduction,這樣也就不會程序切換,就會出現程序...