歡迎您光臨本站 註冊首頁

Linux網路伺服器性能比較的研究

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  

據《矽谷》雜誌2012年第22期刊文稱,高性能網路服務程序在當前的linux環境下應用非常廣泛,不論是主流web伺服器,還是mmo伺服器,都需要高性能的網路伺服器結構提供支撐。就主流的linux網路伺服器模型性能進行比較,得出一般性結論,為以後網路開發人員對網路伺服器的選擇提供一定的參考依據。

關鍵詞:linux;伺服器;性能;比較

1標準tcp客戶端的設計

在客戶端主程序中需要的一般參數包括伺服器端ip地址,伺服器埠,客戶端fork形成的子進程數,子進程向伺服器發送的請求連接數量以及要求伺服器返回的數據位元組數。據此給出客戶端的基本模型:

for(i=0;i

if((pid=fork())==0){ //fork子進程

for(j=0;j

fd=connect(……);//建立到伺服器的tcp連接

write(fd,request,strlen(request));//向伺服器發送返回數

read(fd,reply,nbytes);//讀返回的數據

Close(fd); //關閉套接字

客戶端運行的命令可以如下:./client127.0.0.1888855004000

雖然有比較完整的基於benchmark的基準測試程序用於測試各種web伺服器性能,但就一般性比較各伺服器程序範式,使用上述客戶端模型基本可以滿足。

2Linux網路伺服器分類

2.1常見伺服器分類

傳統意義上將伺服器可以分為2種類型:循環伺服器(iterativeserver)和併發伺服器(concurrentserver)。這樣分類雖然簡單,但卻不夠細化。伺服器的網路模型分類可根據以下依據:是不是以阻塞方式來處理請求,是不是多路復用和使用哪種多路復用函數(如select,poll,epoll);是不是採用多線程技術,線程間的關係該如何組織;是不是採用多進程,一般多進程的調用多是在accept函數前。根據此分類依據,可將伺服器模型大體分為三大類:阻塞式模型、多路復用模型、實時信號模型。

2.2linux網路伺服器模型分析

1)單線程處理,處理流程為:socket-->bind-->listen-->[accept-->read-->write-->close]-->close其中括弧內為伺服器循環。

2)為一個請求分配一個進程或是線程,主線程調用阻塞在accept處,每個新的連接請求到來,都實時為其生成線程處理其請求。但多數情況進程的線程數有限,創建線程的開銷和過多線程後進行上下文切換的開銷,對於真正的系統的設計,該模型只具有理論上的實用性,後面的實驗也驗證這點。

3)伺服器端預派生一定數量進程或線程,讓所有線程都阻塞在accept調用的地方。以前的觀點認為大量進程或線程同時阻塞在accept處時,會產生“驚群”現象,即所有的線程或進程都被同時激活,但只有一個獲取連接描述符並返回,其它線程或進程又轉為睡眠。linux從2.2.9及以後的版本都不存在這個問題,只有一個會被激活。

4)Tcp預先派生進程服務程序,accept使用文件上鎖或者線程上鎖保護模型。一般線程鎖一次只有一個線程可以阻塞在accept處。避免所有預產生的線程都直接阻塞在accept,可以避免驚群問題。而文件鎖不具有通用性,將不參與模型性能比較。

5)主線程處理accept,預派生多個線程(線程池)處理連接。主線程在accept返回以後,將clientfd放入線程的消息隊列,線程池將讀取線程消息隊列然後處理clientfd。這裡主線程只對accept進行操作,快速返回後繼續調用accept,有效的避免了拒絕連接的問題,當加大線程消息隊列的長度時,可以顯著減少消息隊列處的系統調用頻繁度。

3六種伺服器模型的測試比較

3.1實驗結果

客戶端進程數用戶時間(耗費在用戶進程上的cpu時間(s))系統時間(內核在系統調用花費的時間(s))伺服器發送位元組數每個進程處理連接數為

1,迭代伺服器

10(s)0.728045(s)40005000

20.0041.2400840005000

40.0042.4300840005000

100.020001(s)5.85637(s)40005000

150.0320028.9445640005000

100.69204345000

100.772048100005000

10.0280017.78449400050000

2,tcp併發伺服器,每個客戶一個子進程

102.0641340005000

1001.544094000500

20.0124.6082940005000

40.0320016.9764440005000

100.04800216.50140005000

10.10000521.3413400050000

3,tcp預先派生子進程,accept無上鎖保護(最後一項為預派子進程數)

10.0040.8240514000500015

100.0160018.924564000500015

100.0080.61203840005002

100.0200015.89637400050002

1000.0240018.776554000500100

1000.0125.8163640005002

1000.0560036.73242400050020

(相比tcp併發伺服器,處理時間縮短兩至三倍,但預派子進程越多,性能有所下降)

4,tcp併發伺服器,每個客戶一個線程

10.0281.0040640005000

100.0121.284084000500

100.1680112.116840005000

可見性能稍優於進程併發

5,tcp預先派生線程池,每個線程各自accept

100.8560534000500010

100.0120.884055400050010

100.0640049.040574000500010

100.0600036.4724400050002

性能優於為每個客戶創建一個線程,當預派線程變多時性能明顯下降

6,tcp預先創建線程池,主線程統一accept

100.8760544000500010

1001.01206400050010

100.10000610.27664000500010

100.0360027.68848400050002

該模型性能稍遜於模型五,主要是該模型既需要互斥鎖又需要條件變數。

3.2一般性結論

1)縱向比較

一,對於迭代伺服器:客戶進程數與系統處理時間成線性關係,處理相同的連接數,採用多進程的方式發送可以縮短30%~40%的時間。當連接數與進程數相同時,對於返回位元組數多的鏈接,系統花費的時間會多一些,但不會根本上改變系統性能,伺服器發送數據占系統處理時間的一小部分。

二,對於tcp併發伺服器:雖然局部範圍內連接數與系統處理時間的關係具有波動性,但總體仍然可以得出以下結論,對於總數相同的的連接,增大客戶進程數可以縮短系統處理時間;

三,對於tcp預先派生子進程:當預派子進程數相同,客戶進程數增大時,每個鏈接的平均系統處理時間會增加少許。對於當預派子進程數不同時,派生進程少的伺服器可以明顯降低系統處理時間,也就是說,預派子進程變多時,會增加系統負擔,降低系統平均處理效率。

四,對於每個客戶一個線程的tcp併發伺服器:當總連接數相同,客戶連接進程變多時,每次連接的平均時間會有一定增加。

五,tcp預先派生線程池,每個線程各自調用accept:當派生的線程數下降時,系統性能會有一定提高;相同的連接數,客戶端進程變多時,每個連接的處理時間增加。

六,tcp預先創建線程池,主線程統一accept:每個客戶進程發送的連接數相同,進程變多時,單個連接處理時間增加;連接總數相同,客戶進程變多時,處理時間增加。

2)橫向比較

平均時間比較:這裡處理每個連接平均時間最短的是迭代伺服器,這個結果是好多人都沒想到的(究其原因是因為迭代伺服器沒有進程式控制制開銷),第二好的是tcp預先創建線程池,主線程統一accept伺服器模型,它與tcp預先派生線程池,每個線程各自accept伺服器模型性能相當。第四是tcp併發伺服器,每個客戶一個線程伺服器模型。第五是tcp預先派生子進程,accept無上鎖保護伺服器模型。最差的是tcp併發伺服器。

4結束語

本文首先對客戶模型進行設計,設計出一種通用客戶模型。在此基礎上列舉出幾種通用伺服器模型,並就每種模型設計出伺服器程序,對每一種模型進行性能測試。當今網路伺服器所面對的客戶數量增加的壓力越來越大,而linux網路伺服器又是主流的網路伺服器平台,因此設計出高性能的伺服器模型是每個從事linux網路編程人員的心愿。測試所用數據都經過仔細篩選,對實際應用系統的設計具有很高的參考價值。



[火星人 ] Linux網路伺服器性能比較的研究已經有414次圍觀

http://coctec.com/docs/net/show-post-68167.html