.net 的 HttpWebRequest 或者 WebClient 在多線程情況下存在並發連接限制,這個限制在桌面操作系統如 windows xp , windows 7 下默認是2,在服務器操作系統上默認為10. 如果不修改這個並發連接限制,那么客戶端同時可以建立的 http 連接數就只有2個或10個。對於一些諸如瀏覽器或網絡蜘蛛的應用,2個或10個並發數量實在太少,大大影響應用的性能。之所以有這個並發連接限制,是因為 http 1.0 和 http 1.1 標准規定並發連接數最大為2. 不過目前主流的瀏覽器都已經不遵循這個規則了,但 .net framework 依然默認遵循這個規則。
很多文章說用異步方式訪問 HttpWebRequest 可以提高並發性能,但我測試下來,如果不修改這個默認並發連接數,同步或異步方式訪問性能都很不好。
調整這個默認並發連接限制的方法很簡單
只要在程序中設置:
System.Net.ServicePointManager.DefaultConnectionLimit = 512;
這個值最好不要超過1024。
我們也可以在app.config 中對最大並發連接數進行設置,方法如下:
<configuration> <system.net> <connectionManagement> <add address = "http://www.google.com" maxconnection = "512" />
<add address = http://192.168.1.14:8082/ maxconnection = "512" />除 80 之外的端口上承載的應用程序時,該參數必須在 URI 中包含非標准的端口
<add address = "*" maxconnection = "512" /> </connectionManagement> </system.net> </configuration>
修改了這個設置后,並發性能明顯提高,從原來每秒鍾20次直接上升到每秒鍾1000多次。
------------------------------------------------------------------------------------------------------------------------------------------------------------
[轉]關於HTTP服務器每個客戶端2個連接的限制
現摘錄如下:
這幾天在做IIS 6上Web Service (WSE 2.0)的性能測試。在這個過程中陸續發現和解決了一些問題。
其中有一個問題比較有意思。我和項目組的同事發現,不論我們用C#寫的模擬客戶端用多少並發量來連接Web Service,服務器端監測到的並發連接數(性能記數器中的Web Service\Current Connections)總是每客戶端最高2個。這使得我們無法查看服務器在大並發量下的真切反應。
那么為什么服務器會對每客戶端做出最高2個並發量的限制呢?
通過查找資料,我找到了問題的根源。原來,在HTTP 1.1 Spec中針對Persistent Connections提出了這樣的Practical considerations:
Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.
以上內容表明,為了提高HTTP響應時間以及避免產生網絡堵塞,HTTP連接中的客戶端不應該與服務器端建立超過2個的HTTP連接。如果有更多的請求需 要,那么這些請求將被pipeline到這兩個HTTP連接之中,並以異步的方式傳送給服務器端。舉個例子:有上百輛汽車(requests)想從天津開 往北京,但是天津與北京之間最多只允許修建兩條公路(HTTP connection),因此這些汽車要想從天津駛往北京的話,就只能走這兩條公路。
但是,有時的確需要突破這樣的限制。比如我一開始提到的性能測試,我需要用盡可能少的客戶端程序來模擬盡可能多的用戶訪問,而不能為了模擬1000個並發量同時使用500台機器來測。那么應該怎樣通過一個測試應用程序來產生指定的並發數量呢?
不難看出,為了提高單一測試應用程序所產生的並發量,就應該增加兩個指標:網絡客戶端數量和單一客戶端的HTTP連接數量。就我所知,可以通過以下兩種方法來分別提高這兩個指標。
方法一:使用AppDomain
在. NET中,一個AppDomain就被視為網絡連接中的一個客戶端,因此如果希望用一個測試應用程序模擬多個客戶端,那么只須創建多個AppDomain 即可。需要注意的是,對於每一個AppDomain,最高2個的連接限額仍然存在,不同之處只是我們可以使用一個測試應用程序發送超過2個的並發請求了 (現在為了模擬1000個並發量就不需要找500台測試機器了)。請看下面的代碼:
AppDomain appDomain = AppDomain.CreateDomain("");
appDomain.ExecuteAssembly(@"TestClient.exe");
AppDomain.Unload(appDomain);
在這里,我通過調用AppDomain的靜態方法CreateDomain創建了一個新的應用程序域,並要求該應用程序域執行一個應用程序 TestClient.exe。該應用程序將負責向服務器發送請求(最多只能建立兩個連接)。你可以通過多線程的方式來驅動上述代碼,使得大量應用程序域 在近乎相同的時間里被創建,從而就可以模擬指定數量的客戶端,並產生所希望的並發訪問量。
方法二:使用配置文件
除了增加客戶端數量以外,我們還可以增加單一客戶端所能建立的HTTP連接數量。在.NET中實現這一目標非常容易,只需要在客戶端(沒錯,是客戶端!)的配置文件中增加以下幾行即可:
<system.net>
<connectionManagement>
<add address="*" maxconnection="100"/>
</connectionManagement>
</system.net>
其中,connectionManagement節點負責指定客戶端與某一網絡主機之間所能建立的最高連接數量。它在Machine.config文件中 的默認取值就是2。我們完全可以在應用程序級的配置文件中對這一限額做出更改。address屬性表明該連接限額針對的是哪一個網絡地址,*表明所有的網 絡主機;如果寫成address="www.google.com"就表明后面的maxconnection只適用於對google的訪問。
好了,現在就可以根據自己的需要來更改配置了。如果你把maxconnection的取值改成了1000,那么你的測試應用程序與服務器之間所能建立的最高連接數量就是測試用應用程序域的數量 * 1000,測吧!
方法三:
ServicePointManager.DefaultConnectionLimit = 1000;
方法四:
protected override WebRequest GetWebRequest(Uri uri) {
HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(uri);
ServicePoint currentServicePoint = req.ServicePoint;
currentServicePoint.ConnectionLimit = 1000;
return req;
}