喬平安 顏景善 周 敏
(西安郵電大學(xué)計(jì)算機(jī)學(xué)院 西安 710121)
?
基于Linux系統(tǒng)的構(gòu)建高性能服務(wù)器的研究*
喬平安顏景善周敏
(西安郵電大學(xué)計(jì)算機(jī)學(xué)院西安710121)
摘要研究了在Linux環(huán)境下構(gòu)建高性能服務(wù)器的關(guān)鍵技術(shù),Reactor,Proactor事件處理模式,處理并發(fā)訪問量的并發(fā)模式,考慮到現(xiàn)代硬件技術(shù)的發(fā)展,以空間換時(shí)間的思想構(gòu)建高性能服務(wù)器,在理論研究的基礎(chǔ)上,最后在Linux環(huán)境下設(shè)計(jì)了一個(gè)Web服務(wù)器,構(gòu)建過程中充分利用了研究的高性能知識(shí),并通過壓力測試進(jìn)行仿真驗(yàn)證,并分析仿真數(shù)據(jù),證明構(gòu)建的服務(wù)器是可以承受一定的高并發(fā)訪問的。
關(guān)鍵詞高性能服務(wù)器技術(shù); 事件處理模式; 并發(fā)模式; 線程池; 進(jìn)程池
Class NumberTP302.1
隨著因特網(wǎng)的發(fā)展,互聯(lián)網(wǎng)的使用人數(shù)及信息量的爆炸式增長,對(duì)于服務(wù)器穩(wěn)定高效的處理高并發(fā)請(qǐng)求越來越重要[1],例如Facebook在2012年擁有8.367億的獨(dú)立訪問者。如果對(duì)于同時(shí)大量的訪問,不能快速處理,那么對(duì)于企業(yè)來說將是致命的打擊,導(dǎo)致客戶的大量流失。所以構(gòu)建高性能服務(wù)器顯得越來越重要。通過對(duì)在Linux環(huán)境下構(gòu)建高性能服務(wù)器研究的基礎(chǔ)上,運(yùn)用所研究的知識(shí)構(gòu)建一個(gè)Web服務(wù)器,并進(jìn)行壓力測試。所研究的構(gòu)建高性能服務(wù)器的知識(shí)主要包括:在Linux環(huán)境下的I/O模型以及兩種高效的事件處理模式,兩種并發(fā)處理模式以及在半同步/半異步模式下衍生出的半同步/半反應(yīng)堆模式,根據(jù)現(xiàn)在服務(wù)器行業(yè)的發(fā)展,硬件的發(fā)展速度明顯高于軟件,針對(duì)這種特點(diǎn)則有了以空間換取時(shí)間的思想的提出,運(yùn)用在高性能服務(wù)器上的具體表現(xiàn)形式則是進(jìn)程池,線程池、內(nèi)存池、連接池的提出及應(yīng)用,運(yùn)用高性能的定時(shí)器可以提高服務(wù)器性能,構(gòu)建穩(wěn)定的服務(wù)器可以運(yùn)用統(tǒng)一事件源的思想。
構(gòu)建高性能服務(wù)器的理論方法如下。
2.1Linux環(huán)境下I/O模型
選取合適的I/O模型對(duì)服務(wù)器的性能有著重要的影響,Linux環(huán)境下I/O模型[2]分為四種:
1) 阻塞I/O,程序阻塞于讀寫函數(shù)。
2) I/O復(fù)用,程序阻塞于I/O復(fù)用系統(tǒng)調(diào)用,但可以同時(shí)監(jiān)聽多個(gè)I/O事件。
3) SIGIO信號(hào),信號(hào)觸發(fā)讀寫就緒事件,用戶程序執(zhí)行讀寫操作,程序沒有阻塞階段。
4) 異步I/O,內(nèi)核執(zhí)行讀寫操作并觸發(fā)讀寫完成事件。程序沒有阻塞階段。
由各個(gè)I/O模型的特點(diǎn)可知,對(duì)于高性能服務(wù)器處理高并發(fā)訪問運(yùn)用的是I/O復(fù)用技術(shù)以及異步I/O技術(shù)[3]。
在Linux環(huán)境下的I/O復(fù)用技術(shù)包括:select、poll、epoll[4]系列函數(shù)。三者的區(qū)別如下:
1) 事件集合:對(duì)于select,用戶通過三個(gè)參數(shù)分別傳入感興趣的可讀、可寫及異常等事件,內(nèi)核通過對(duì)這些參數(shù)在線修改來反饋其中的就緒事件,這使得用戶每次調(diào)用select都要重置這三個(gè)參數(shù)。對(duì)于poll,統(tǒng)一處理所有事件類型,只需要一個(gè)事件集參數(shù),用戶通過pollfd.events傳入感興趣的事件,內(nèi)核通過修改pollfd.revents反饋其中就緒的事件。對(duì)于epoll,由內(nèi)核事件表直接接管用戶感興趣的所有事件,因此每次調(diào)用epoll_wait時(shí),無須反復(fù)傳入用戶感興趣的事件。epoll_wait系統(tǒng)調(diào)用的參數(shù)events僅用來反饋就緒的事件。
2) 應(yīng)用程序索引就緒文件描述符的時(shí)間復(fù)雜度:select:O(n),poll:O(n),epoll:O(1)。
3) 最大支持文件描述符數(shù):select:一般有最大值限制。poll,epoll取決于硬件。
4) 工作模式:select,poll:工作在LT模式下,epoll:支持ET高效模式。
5) 內(nèi)核實(shí)現(xiàn)和工作效率:select,poll:采用輪詢方式來檢測就緒事件,算法時(shí)間復(fù)雜度為O(n),epoll:采用回調(diào)方式來檢測就緒事件,算法時(shí)間復(fù)雜度為O(1)。
經(jīng)過以上分析可知處理大規(guī)模高并發(fā)的數(shù)據(jù)訪問用I/O復(fù)用中的epoll[5]模型優(yōu)勢明顯。
異步I/O技術(shù):注冊(cè)的是讀完成或?qū)懲瓿墒录?真正的讀寫由內(nèi)核完成,效率高,主要的函數(shù)包括aio_read,aio_write,異步I/O技術(shù)也可用于高并發(fā)的數(shù)據(jù)訪問。
2.2事件處理模式
盡管服務(wù)器的種類眾多,但是其基本框架都是一樣的[6],基本框架如圖1所示。
· I/O處理單元:對(duì)于單個(gè)服務(wù)器程序:主要進(jìn)行客戶的連接,讀寫網(wǎng)絡(luò)數(shù)據(jù)。但有時(shí)也可能在邏輯單元來完成。對(duì)于服務(wù)器集群:專門接入服務(wù)器,實(shí)現(xiàn)負(fù)載均衡。

圖1 服務(wù)器基本框架
· 邏輯單元:對(duì)于單個(gè)服務(wù)器程序:一個(gè)邏輯單元通常是一個(gè)業(yè)務(wù)進(jìn)程或線程,處理并分析客戶數(shù)據(jù)。對(duì)于服務(wù)器集群:一個(gè)邏輯單元通常是一臺(tái)邏輯服務(wù)器,集群有多臺(tái)邏輯服務(wù)器,實(shí)現(xiàn)對(duì)客戶請(qǐng)求的并行處理。
· 網(wǎng)絡(luò)存儲(chǔ)單元:對(duì)于單個(gè)服務(wù)器程序,是本地?cái)?shù)據(jù)庫,文件或緩存。對(duì)于服務(wù)器集群,是數(shù)據(jù)庫服務(wù)器。
· 請(qǐng)求隊(duì)列:對(duì)于單個(gè)服務(wù)器程序,是各單元間的通信方式。對(duì)于服務(wù)器集群,是各服務(wù)器間永久的TCP連接。
構(gòu)建高性能服務(wù)器的網(wǎng)絡(luò)設(shè)計(jì)模式有兩種:Reactor和Proactor事件處理模式。圖2為Reactor處理模式,圖3為Proactor處理模式[2]。

圖2 Reactor處理模式

圖3 Proactor處理模式
2.3并發(fā)處理模式
并發(fā)模式是指I/O處理單元和多個(gè)邏輯單元之間協(xié)調(diào)完成任務(wù)的方法。服務(wù)器并發(fā)處理模式包括兩種:半同步/半異步模式,領(lǐng)導(dǎo)者/追隨者模式[7]。
高效的半同步半異步模式:在主線程中管理監(jiān)聽socket,當(dāng)有連接到來時(shí),則接受連接,并將連接socket派發(fā)到工作線程,在工作線程中利用epoll系列函數(shù)注冊(cè)此socket,進(jìn)行任務(wù)的處理。此模式最大的優(yōu)勢在于一個(gè)工作線程可以獨(dú)立地管理多個(gè)連接。
半同步/半異步模式的一個(gè)變種是半同步/半反應(yīng)堆模式,它在主線程中管理監(jiān)聽/連接socket,當(dāng)任務(wù)到來時(shí),將任務(wù)插入請(qǐng)求隊(duì)列中,由于多個(gè)線程共享此隊(duì)列,所以需要進(jìn)行加鎖,并運(yùn)用信號(hào)量來通知其它線程來處理此任務(wù)。此模式由于需要加鎖會(huì)浪費(fèi)CPU,并且每個(gè)工作線程同時(shí)只能處理一個(gè)任務(wù)。
領(lǐng)導(dǎo)者/追隨者模式是多個(gè)工作線程輪流獲得事件源集合,輪流監(jiān)聽、分發(fā)和處理請(qǐng)求任務(wù)的一種模式。在任意時(shí)刻,僅有一個(gè)領(lǐng)導(dǎo)者,領(lǐng)導(dǎo)者監(jiān)聽事件的發(fā)生,事件發(fā)生時(shí),從追隨者中推選出新的領(lǐng)導(dǎo)者,并處理任務(wù),由此實(shí)現(xiàn)了并發(fā)。
2.4提高服務(wù)器性能的其他建議
由于硬件技術(shù)的快速發(fā)展,現(xiàn)在服務(wù)器一般都不缺乏硬件資源,所以可以運(yùn)用空間換取時(shí)間的思想。池的運(yùn)用就是運(yùn)用這一思想,池包括:線程池,進(jìn)程池,內(nèi)存池,連接池。
進(jìn)程池[8~9]、線程池則是在服務(wù)器啟動(dòng)時(shí)創(chuàng)建,若要有任務(wù)請(qǐng)求時(shí)可以直接拿來用,這樣就避免了因?yàn)閯?chuàng)建進(jìn)程或線程所耗費(fèi)的大量資源。進(jìn)程池模型如圖4所示。

圖4 進(jìn)程池模型
線程池模型與進(jìn)程池類似,進(jìn)程池創(chuàng)建子進(jìn)程的數(shù)目在3~10個(gè),線程池中的線程數(shù)量應(yīng)該和CPU數(shù)量差不多。
數(shù)據(jù)復(fù)制[10]:在構(gòu)建高性能的服務(wù)器時(shí)盡量避免不必要的復(fù)制操作,可以通過一些高級(jí)的IO函數(shù):例如sendfile,writev,splice,tee等,也可以通過共享內(nèi)存來避免兩個(gè)進(jìn)程用戶空間的大量拷貝,從而提高服務(wù)器的性能。
并發(fā)程序需要考慮加鎖的問題,鎖不但不處理任何業(yè)務(wù)請(qǐng)求,而且還降低了資源的利用率,因此應(yīng)盡量避免加鎖,如果必須要加鎖,也要盡量減小鎖的粒度,例如讀寫鎖。
使用高性能的定時(shí)器,可以高效地處理眾多的定時(shí)事件。高性能定時(shí)器包括時(shí)間輪和時(shí)間堆,時(shí)間輪采用了哈希散列的思想;時(shí)間堆采用了堆排序,并且是小頂堆。
統(tǒng)一事件源是將I/O事件,定時(shí)事件,信號(hào)統(tǒng)一起來,通過在信號(hào)處理函數(shù)中將發(fā)生的信號(hào)通過管道來傳給主線程或主進(jìn)程,從而達(dá)到了統(tǒng)一事件源的目的,提高了服務(wù)器的穩(wěn)定性。
利用半同步/半反應(yīng)堆的并發(fā)模式及線程池實(shí)現(xiàn)一個(gè)高性能Web服務(wù)器。總體的設(shè)計(jì)思路是在服務(wù)器啟動(dòng)時(shí)即先啟動(dòng)設(shè)計(jì)好的線程池,在主線程中管理監(jiān)聽socket以及連接socket,當(dāng)有數(shù)據(jù)到來時(shí),則接受數(shù)據(jù)并初始化任務(wù)類,將任務(wù)類插入到工作隊(duì)列中,工作隊(duì)列通過信號(hào)量來通知空閑的工作線程,然后在工作線程中調(diào)用任務(wù)類的處理函數(shù)對(duì)http協(xié)議的數(shù)據(jù)進(jìn)行解析,通過解析結(jié)果進(jìn)行相應(yīng)的處理,并將處理結(jié)果寫入用戶緩沖,然后修改內(nèi)核事件表,注冊(cè)寫就緒事件,最后將處理好的數(shù)據(jù)發(fā)送給客戶端。具體設(shè)計(jì)過程如下。
3.1封裝線程同步機(jī)制
在設(shè)計(jì)線程同步機(jī)制包裝類時(shí),要將實(shí)現(xiàn)線程同步的信號(hào)量以及互斥鎖有關(guān)的線程同步函數(shù)封裝進(jìn)去。通過信號(hào)量來通知工作線程在任務(wù)隊(duì)列中有任務(wù)需要處理;由于工作線程共享同一個(gè)工作隊(duì)列所以需要使用互斥鎖,對(duì)共享隊(duì)列進(jìn)行獨(dú)占式的訪問。在具體的封裝時(shí),由于在構(gòu)造函數(shù)中沒有返回值,所以可以通過在構(gòu)造函數(shù)中拋出異常,在主線程中來進(jìn)行對(duì)異常情況的捕獲與處理。
3.2封裝線程池類
在線程池類中封裝了線程池的構(gòu)造函數(shù)、析構(gòu)函數(shù)以及往請(qǐng)求隊(duì)列中添加任務(wù)的函數(shù),還有工作線程運(yùn)行的函數(shù),它不斷地從工作隊(duì)列中取出任務(wù)并執(zhí)行之。在設(shè)計(jì)其構(gòu)造函數(shù)時(shí),注意pthread_create函數(shù)的回調(diào)函數(shù)必須是靜態(tài)的,并且將類對(duì)象作為參數(shù)傳遞給回調(diào)函數(shù),這樣才能調(diào)用線程池中的動(dòng)態(tài)方法。在任務(wù)添加函數(shù)中要先進(jìn)行加鎖,然后添加任務(wù)并解鎖,此時(shí)才能發(fā)出信號(hào)給其他空閑工作線程來處理任務(wù)。
3.3封裝任務(wù)類
在封裝的任務(wù)類中,最主要完成的任務(wù)就是通過一系列的函數(shù)完成對(duì)http數(shù)據(jù)的解析,以及根據(jù)解析結(jié)果對(duì)http方法進(jìn)行處理。在解析中從狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)移圖如圖5所示。

圖5 從狀態(tài)機(jī)狀態(tài)轉(zhuǎn)移圖
在主狀態(tài)機(jī)中記錄當(dāng)前的狀態(tài),根據(jù)當(dāng)前的狀態(tài)來對(duì)從狀態(tài)機(jī)解析出來的行進(jìn)行解析,并在主狀態(tài)機(jī)中完成狀態(tài)的轉(zhuǎn)移。
運(yùn)用施壓程度最高的I/O復(fù)用方式對(duì)設(shè)計(jì)的服務(wù)器進(jìn)行施壓測試[11]。如果運(yùn)用多線程、多進(jìn)程進(jìn)行壓力測試時(shí),線程和進(jìn)程本身的調(diào)用會(huì)消耗一定的資源。
壓力測試程序思想是通過建立指定數(shù)量的連接,并運(yùn)用epoll模型在循環(huán)中不斷的向服務(wù)器發(fā)送數(shù)據(jù)或從服務(wù)器接受數(shù)據(jù)。仿真測試如圖6~圖9所示。

圖6 啟動(dòng)服務(wù)器程序

圖7 啟動(dòng)壓力測試程序

圖8 壓力測試程序

圖9 服務(wù)器程序
仿真結(jié)果分析:壓力測試程序:壓力測試程序先建立了1000個(gè)客戶連接,如圖7,然后這1000個(gè)客戶同時(shí)向服務(wù)器端發(fā)出請(qǐng)求,請(qǐng)求內(nèi)容如下:"GET http://localhost/index.html HTTP/1.1 Connection: keep-alive xxxxxxxxxxxx",如圖7所示向服務(wù)器端發(fā)送了80個(gè)字節(jié)的請(qǐng)求數(shù)據(jù)。服務(wù)器程序:服務(wù)器程序啟動(dòng)時(shí)如圖6所示先建立了七個(gè)線程池以及接受存儲(chǔ)任務(wù)類的內(nèi)存池,然后等待客戶請(qǐng)求的到來,當(dāng)客戶請(qǐng)求到來時(shí),服務(wù)器端程序?qū)φ?qǐng)求進(jìn)行了分析如圖9:"got 1 http line: Get http://localhost/index.html HTTP/1.1 got 1 http line: Connection keep-alive got 1 http line: ",分析之后并做了相應(yīng)的應(yīng)答:"HTTP/1.1 404 Not Found Content-Length: 49 Connection:keep-alive The requested file was not found on this server. ",服務(wù)器端將應(yīng)答結(jié)果返回客戶端,客戶端此時(shí)接收到的數(shù)據(jù)如下:"read in 119 bytes from socket 54 with content: HTTP/1.1 404 Not Found Content-Length: 49 Connection: keep-alive The requested file was not found on this server. ",通過對(duì)仿真結(jié)果的分析可知,在客戶端高并發(fā)的訪問下,服務(wù)器能夠穩(wěn)定并及時(shí)的處理客戶請(qǐng)求,所以設(shè)計(jì)的Web服務(wù)器能夠處理一定的高并發(fā)任務(wù)請(qǐng)求。
參 考 文 獻(xiàn)
[1] 朱志祥,許輝輝,王雄.基于云計(jì)算的彈性負(fù)載均衡方案[J].西安郵電大學(xué)學(xué)報(bào),2013,18(6):43-47.
ZHU Zhixiang, XU Huihui, WANG Xiong. Elastic load balancing scheme based on Cloud Computing[J]. Journal of Xi’an University of Posts and Telecommunications,2013,18(6):43-47.
[2] 黃欣.自適應(yīng)網(wǎng)絡(luò)I/O模型的研究與實(shí)現(xiàn)[D].廣州:華南理工大學(xué),2012:7-10.
HUANG Xin. Research and implementation of adaptive network I/O model[D]. Guangzhou: South China University of Technology,2012:7-10.
[3] 彭妮.階段化異步事件驅(qū)動(dòng)高性能Web服務(wù)器[D].長沙:長沙理工大學(xué),2006:12-17.
PENG Ni. Stage asynchronous event driven high performance Web server[D]. Changsha: Changsha University of Science and Technology,2006:12-17.
[4] 張超,潘旭東.Linux下基于EPOLL機(jī)制的海量網(wǎng)絡(luò)信息處理模型[J].強(qiáng)激光與粒子束,2013,25(S1):46-50.
ZHANG Chao, PAN Xudong. A mass network information processing model based on EPOLL mechanism under Linux[J]. Intense Laser and Particle Beam,2013,25(S1):46-50.
[5] 吳敏,熊文龍.基于Linux的高性能服務(wù)器端的設(shè)計(jì)與研究[J].交通與計(jì)算機(jī),2007,25(1):129-131.
WU Min, XIONG Wenlong. Design and research of high performance server based on Linux[J]. Transportation and Computer,2007,25(1):129-131.
[6] Lee, Yang-Sun. High performance web server architecture with Kernel-level caching[J]. Cluster Computing,2013,16(3):339-346.
[7] 游雙.高性能服務(wù)器編程[M].北京:北京機(jī)械出版社,2013:145-152.
YOU Shuang. High performance server programming[M]. Beijing: Beijing Machinery Press,2013:145-152.
[8] Xu Zongyu, Wang Xingxuan. A modified round_robin load balancing algorithm for cluster_based web servers[C]//Nanjing: IEEE Computer Society,2014:3580-3584.
[9] 謝曉燕,張靜雯.一種基于Linux集群技術(shù)的負(fù)載均衡算法[J].西安郵電大學(xué)學(xué)報(bào),2014,19(3):64-68.
XIE Xiaoyan, ZHANG Jingwen. A load balancing algorithm based on Linux cluster technology[J]. Journal of Xi’an University of Posts and Telecommunications,2014,19(3):64-68.
[10] Ke, Ya Ming, Wang, Yong Bin, Li, Ying. A high performance web server based on asynchronous and zero-copy[J]. Applied Mechanics and Materials,2014,543(2):3118-3121.
[11] 趙麗娟.Web應(yīng)用程序滲透測試方法研究[D].長沙:中南大學(xué),2014:4-5.
ZHAO Lijuan. Research on Web application penetration testing method[D]. Changsha: Hunan: Central South University,2014:4-5.
收稿日期:2015年9月1日,修回日期:2015年10月27日
作者簡介:喬平安,男,副教授,碩士生導(dǎo)師,研究方向:數(shù)據(jù)庫技術(shù)、計(jì)算機(jī)網(wǎng)絡(luò)。顏景善,男,碩士研究生,研究方向:Web服務(wù)器開發(fā)。周敏,女,碩士研究生,研究方向:計(jì)算機(jī)網(wǎng)絡(luò)。
中圖分類號(hào)TP302.1
DOI:10.3969/j.issn.1672-9722.2016.04.021
Construction of High Performance Server System Based on Linux
QIAO PinganYAN JingshanZHOU Min
(School of Computer, Xi’an University of Posts and Telecommunications, Xi’an710121)
AbstractThe key technology of high performance server construction based on the Linux, Reactor and Proactor event handling model, concurrent processing mode facing to amounts of accessing are introduced. Taking into account the development of modern hardware technology, so a high performance server space is put forward for time in thought. Making full use of the high performance knowledge, finally a Web server of high performance is designed. According to the experiment results, the Web server is constructed to withstand certain high concurrent accessing.
Key Wordstechnolgy of high performance server, event handling model, concurrent model, thread pool, process pool