吉 利,潘林云,劉 姚
(南京郵電大學(xué) 通信與信息工程學(xué)院,江蘇 南京 210003)
線程池技術(shù)在網(wǎng)絡(luò)服務(wù)器中的應(yīng)用
吉 利,潘林云,劉 姚
(南京郵電大學(xué) 通信與信息工程學(xué)院,江蘇 南京 210003)
目前的網(wǎng)絡(luò)服務(wù)器大多為C/S架構(gòu),其線程響應(yīng)客戶端要么短且頻繁,要么長(zhǎng)而連續(xù),這兩種服務(wù)請(qǐng)求均要求服務(wù)器根據(jù)系統(tǒng)負(fù)載提供穩(wěn)定的響應(yīng)時(shí)間,并在高并發(fā)情況下保證服務(wù)器系統(tǒng)的工作穩(wěn)定性。傳統(tǒng)的多線程技術(shù)雖能通過(guò)并發(fā)服務(wù)器發(fā)揮較好的性能,但線程頻繁的創(chuàng)建與銷毀會(huì)導(dǎo)致巨大的系統(tǒng)開銷。為此,在研究線程池技術(shù)機(jī)理的基礎(chǔ)上,針對(duì)常見的線程池容量估算的弊端,提出了經(jīng)優(yōu)化的池線程容量估算方法。該方法引入經(jīng)優(yōu)化的池線程,以解決因大量客戶端服務(wù)請(qǐng)求所導(dǎo)致的服務(wù)器不穩(wěn)定問(wèn)題。線程池性能測(cè)試與驗(yàn)證結(jié)果表明,采用所提出的線程池容量估算方法和線程池策略,有效地降低了因頻繁創(chuàng)建線程而導(dǎo)致的系統(tǒng)開銷,既保證了高負(fù)載條件下服務(wù)器的穩(wěn)定性,又能夠?yàn)榉?wù)器提供穩(wěn)定的吞吐量。
多線程;線程池;線程池容量;服務(wù)器
隨著計(jì)算機(jī)技術(shù)的發(fā)展,計(jì)算機(jī)計(jì)算性能得到了質(zhì)的飛躍,合理使用多線程技術(shù)較傳統(tǒng)的單線程能夠顯著提升系統(tǒng)的吞吐量與響應(yīng)速度,特別在高并發(fā)訪問(wèn)的情形下。電子商務(wù)[1]、消息中間件和其他基于網(wǎng)絡(luò)的應(yīng)用程序部分取決于網(wǎng)絡(luò)服務(wù)器響應(yīng)的及時(shí)和可靠性。多線程系統(tǒng)[2],由于系統(tǒng)資源的有效利用和共享內(nèi)存多處理器架構(gòu)的普及已成為服務(wù)器實(shí)現(xiàn)的必然選擇。然而在訪問(wèn)頻率高且服務(wù)時(shí)間短的情況下,創(chuàng)建和銷毀線程將消耗巨大的系統(tǒng)資源[3]。
線程池中的線程可以重新使用,線程的創(chuàng)建和銷毀只發(fā)生一次。通過(guò)線程池使得多個(gè)任務(wù)重用線程,大大降低了線程創(chuàng)建與銷毀的系統(tǒng)開銷[4]。且多線程的并發(fā)執(zhí)行,能夠充分使用服務(wù)器主機(jī)資源。
傳統(tǒng)的線程池策略采用固定大小的核心線程,即使在低負(fù)載的情況下,線程切換也會(huì)引起巨大的系統(tǒng)開銷。為此,提出了線程池容量分配方法,保證在系統(tǒng)低負(fù)載與高負(fù)載的情況下,均能得到較高的性能[5]。
線程池包含幾個(gè)重要的參數(shù),工作線程,線程容量與緩存客戶端請(qǐng)求的請(qǐng)求隊(duì)列。線程池的工作原理如圖1所示。請(qǐng)求隊(duì)列用于緩存客戶端請(qǐng)求,線程用于執(zhí)行客戶端的每一次請(qǐng)求,工作線程從請(qǐng)求隊(duì)列取出請(qǐng)求,用可重用線程處理請(qǐng)求的任務(wù),并在任務(wù)完成后向客戶端返回信息。
圖1 線程池的核心工作流程
當(dāng)向線程池提交新的任務(wù)時(shí),線程池執(zhí)行以下規(guī)則來(lái)保證系統(tǒng)對(duì)客戶端的響應(yīng):
(1)工作線程用于輪詢接受新的客戶端請(qǐng)求,如果線程池有足夠的空閑線程,則直接提交給線程。若線程池已滿,則進(jìn)入步驟(2)。
(2)線程池判斷請(qǐng)求隊(duì)列是否已滿,若未滿則工作線程將該請(qǐng)求添加到請(qǐng)求隊(duì)列中;若已滿則向客戶端返回服務(wù)器忙信息[6]。
(3)線程池判斷是否有空閑線程以及請(qǐng)求隊(duì)列是否有未完成的請(qǐng)求任務(wù),循環(huán)從請(qǐng)求隊(duì)列中取出請(qǐng)求任務(wù)交給空閑線程執(zhí)行。
(4)若線程池沒(méi)有空閑,且線程池的請(qǐng)求緩存隊(duì)列已經(jīng)存在大量緩存請(qǐng)求,可以適當(dāng)創(chuàng)建新的線程來(lái)服務(wù)請(qǐng)求[7]。
線程池的容量單方面決定服務(wù)器的吞吐量性能參數(shù),如果容量過(guò)小且并發(fā)請(qǐng)求數(shù)量超過(guò)該容量,請(qǐng)求將會(huì)加入阻塞隊(duì)列,若隊(duì)列中已包含大量的已緩存請(qǐng)求,則對(duì)系統(tǒng)的響應(yīng)時(shí)間影響巨大。同時(shí)若線程池容量過(guò)大,線程的上下文切換也會(huì)造成巨大的系統(tǒng)開銷[8]。
圖2展示了當(dāng)線程池容量小于CPU的核心數(shù)目時(shí),CPU的利用率、系統(tǒng)的響應(yīng)時(shí)間隨請(qǐng)求數(shù)量增加的變化情況。
由于線程池容量較小,并沒(méi)有充分利用CPU的全部資源,所以CPU使用率一直處于一個(gè)較低的水平,處理器的性能并沒(méi)有被充分利用。在請(qǐng)求隊(duì)列滿時(shí),服務(wù)器應(yīng)用開始拒絕新的客戶端請(qǐng)求,此時(shí)到達(dá)服務(wù)器的吞吐量。
圖3展示了高容量線程池CPU的利用率、系統(tǒng)的響應(yīng)時(shí)間隨請(qǐng)求數(shù)量增加的變化情況。
圖2 響應(yīng)時(shí)間與請(qǐng)求數(shù)目的關(guān)系
圖3 CPU利用率與請(qǐng)求數(shù)目的關(guān)系
并發(fā)用戶請(qǐng)求數(shù)量增加,服務(wù)器創(chuàng)建相同數(shù)量的線程來(lái)服務(wù)請(qǐng)求,此時(shí)CPU很容易達(dá)到滿載狀態(tài),但由于操作系統(tǒng)中存在大量線程,系統(tǒng)資源大量消耗在線程的上下文切換中。此時(shí)服務(wù)器的響應(yīng)時(shí)間也會(huì)增加。所以線程池容量要避免設(shè)置太小或太大,太小不能充分使用CPU的性能,太大會(huì)造成頻繁的上下文切換,帶來(lái)巨大的系統(tǒng)開銷。所以線程池容量需要根據(jù)負(fù)載和部署條件動(dòng)態(tài)改變。
最佳容量大小可以通過(guò)設(shè)置等比例間隔通過(guò)實(shí)際壓力測(cè)試獲取最優(yōu)結(jié)果。在計(jì)算密集型系統(tǒng)執(zhí)行中能夠獲得最佳的CPU利用率[9]。然而在I/O密集型系統(tǒng),需要用等待概率比例來(lái)估算任務(wù)的執(zhí)行時(shí)間。Little’s Law公式為:
(1)
其中,W為請(qǐng)求的平均處理時(shí)間;L為長(zhǎng)時(shí)間觀察得到的平均請(qǐng)求數(shù)量;λ為新請(qǐng)求的到達(dá)率。
例如每秒有10個(gè)請(qǐng)求到達(dá),并且每個(gè)請(qǐng)求消耗1秒進(jìn)行處理。這種情況下需要?jiǎng)?chuàng)建具有10個(gè)線程容量的線程池,從而保證正常的響應(yīng)時(shí)間。
服務(wù)器性能以該服務(wù)器的響應(yīng)時(shí)間、吞吐量與CPU利用率來(lái)衡量。系統(tǒng)可利用的資源包括CPU核心數(shù)目與內(nèi)存等。處理器執(zhí)行周期衡量了處理器的處理速度,同時(shí)也是線程池管理的主要資源[10]。
JDK從1.5開始提供了ThreadPoolExecutor類管理線程池,該類提供了一系列接口配置與實(shí)時(shí)定制線程池容量,其可配置參數(shù)為CorePoolSize(核心大小)、MaximumPoolSize(最大值)與KeepAliveTime(線程存活時(shí)間)[11]。其中核心線程池尺寸可以通過(guò)設(shè)置這三個(gè)參數(shù)來(lái)達(dá)到線程池最優(yōu)性能。而最大線程池尺寸一般不超過(guò)系統(tǒng)的資源限制。給出公式如下:
(2)
其中,Nt為需要設(shè)置的核心線程數(shù)目;Nc為當(dāng)前CPU的可用核心數(shù);Nu為預(yù)期的CPU核心利用率,為任務(wù)的等待時(shí)間與計(jì)算時(shí)間的比值。
構(gòu)建簡(jiǎn)單的網(wǎng)絡(luò)服務(wù)器,用Java代碼實(shí)現(xiàn)服務(wù)器主線程代碼片段(服務(wù)器綁定端口為8080),如下:
ThreadPoolExecutor exec=prepareThreadPool();
ServerSocket listener=new ServerSocket(8080);
while(true) {
Socket sock=listener.accept();
exec.execute(new Task(sock));
}
線程池線程的任務(wù)是服務(wù)用戶的響應(yīng),并模擬出1 ms的運(yùn)算延時(shí)[1]。
public class Task implementsRunnable {
private Socketsocket;
public Task(Socket socket) {
this.socket=socket;
}
public void run() {
for(longi=0;i<10;i++);
try {
outPutData(socket);
}catch (IOException e) {
e.printStackTrace();
}
}
性能測(cè)試從CPU的利用率與響應(yīng)時(shí)間兩個(gè)參數(shù)進(jìn)行測(cè)試[12]。服務(wù)器為每個(gè)請(qǐng)求執(zhí)行0.1 ms的服務(wù)時(shí)間。并且預(yù)期的CPU利用率為60%,請(qǐng)求的平均等待時(shí)間與計(jì)算時(shí)間之比為500(預(yù)期等待時(shí)間為0.2 s),根據(jù)容量估算公式得到相應(yīng)的估算容量為600[13]。
在測(cè)量CPU利用率上,用戶并發(fā)數(shù)采樣點(diǎn)分別為[1,2,4,8,16,32,64,128,256,512,1 024]。監(jiān)控CPU使用率,并通過(guò)Matlab繪制曲線[14-15]。
其CPU利用率如圖4所示。在核心并發(fā)請(qǐng)求數(shù)不超過(guò)600時(shí),CPU利用率線性增加,由于線程池并發(fā)線程數(shù)的影響,CPU利用率逐漸上升并穩(wěn)定。
圖4 CPU利用率與請(qǐng)求數(shù)目的關(guān)系
測(cè)試響應(yīng)時(shí)間時(shí),并發(fā)請(qǐng)求數(shù)從0至1 200,相鄰采樣間隔為50。測(cè)量每組給定的并發(fā)請(qǐng)求數(shù)目下的系統(tǒng)平均響應(yīng)時(shí)間,記錄并繪圖。
其響應(yīng)時(shí)間隨并發(fā)連接數(shù)的關(guān)系如圖5所示。在并發(fā)連接600以內(nèi)可以保證穩(wěn)定的系統(tǒng)響應(yīng)時(shí)間(ms)。由于資源的競(jìng)爭(zhēng)與大量請(qǐng)求的入隊(duì),系統(tǒng)的響應(yīng)時(shí)間相應(yīng)增加,當(dāng)達(dá)到系統(tǒng)的最高負(fù)載后,拒絕新的請(qǐng)求。
圖5 CPU利用率與請(qǐng)求數(shù)目的關(guān)系
為了降低因頻繁創(chuàng)建線程而導(dǎo)致的巨大系統(tǒng)開銷,在研究線程池工作原理的基礎(chǔ)上,提出了線程池容量的估算方法。以服務(wù)器的CPU使用率與系統(tǒng)響應(yīng)時(shí)間作為衡量標(biāo)準(zhǔn),對(duì)線程池容量估算方法進(jìn)行了有效性測(cè)試。結(jié)果表明,采用該方法的服務(wù)器在各種負(fù)載條件下均能滿足有效的CPU利用率與穩(wěn)定的系統(tǒng)響應(yīng)時(shí)間,既保證了整體穩(wěn)定性,又能提供穩(wěn)定的吞吐量。
[1] 張垠波.線程池技術(shù)在并發(fā)服務(wù)器中的應(yīng)用[J].計(jì)算機(jī)與數(shù)字工程,2012,40(7):153-156.
[2] Ling Yibei,Mullen T,Lin Xiaola.Analysis of optimal thread pool size[J].ACM SIGOPS Operating Systems Review,2000,34(2):43-45.
[3] 李 昊,劉志鏡.線程池技術(shù)的研究[J].現(xiàn)代電子技術(shù),2004,27(3):77-80.
[4] 詹新林,王公亭,徐曉鐘.基于線程池?cái)?shù)據(jù)分析系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].微計(jì)算機(jī)信息,2008,24(33):266-268.
[5] 張堯?qū)W,宋 虹,張 高.計(jì)算機(jī)操作系統(tǒng)教程[M].第4版.北京:清華大學(xué)出版社,2013.
[6] 封 瑋,周世平.Java中的線程池及實(shí)現(xiàn)[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2004(8):16-18.
[7] 王俊峰.一種實(shí)時(shí)集群系統(tǒng)負(fù)載均衡通用模型的研究及應(yīng)用[D].長(zhǎng)沙:湖南大學(xué),2008.
[8] 歐昌華,李炳法.線程池在網(wǎng)絡(luò)服務(wù)器程序中的應(yīng)用[J].信息技術(shù),2002(5):11-14.
[9] 宋立昊.基于線程池的WEB服務(wù)器實(shí)現(xiàn)和監(jiān)測(cè)[D].長(zhǎng)春:吉林大學(xué),2011.
[10] 王 華,馬 亮,顧 明.線程池技術(shù)研究與應(yīng)用[J].計(jì)算機(jī)應(yīng)用研究,2005,22(11):141-142.
[11] Pyarali I,Spivak M,Cytron R,et al.Evaluating and optimizing thread pool strategies for real-time CORBA[J].ACM SIGPLAN Notices,2001,36(8):214-222.
[13] 劉雪梅.服務(wù)器端軟件性能分析和診斷[M].北京:北京郵電大學(xué)出版社,2011.
[14] Belkin R.Mechanism for obtaining a thread from,and returning a thread to,a thread pool without attaching and detaching:U.S.,6 766 349[P].2004-07-20.
[15] 許俊奎,徐鳳剛,潘 清.Web服務(wù)器性能測(cè)試工具的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)測(cè)量與控制,2005,13(11):1204-1206.
Application of Thread Pool Technique in Network Server
JI Li,PAN Lin-yun,LIU Yao
(College of Communications and Systems Engineering,Nanjing University of Posts and Telecommunications,Nanjing 210003,China)
Network servers often use C/S architecture as the main framework currently.The server needs to create a thread frequently in response to a client short or long and continuous service requests.Each type of server requests are required to be able to provide a stable system load according to the response time for the request and guarantee the stability of the server system under the high concurrency.Traditional multi-threading technology can provide excellent performance in the concurrent server,but can lead to huge system overhead because of its frequent thread creation and destruction.An optimization method for estimating the capacity has been proposed according to the disadvantages of common thread pool capacity estimation so as to improve the thread pool server performance,in which the introduction of the thread pool is employed to solve the instability because of a large number of client request thread creation and destruction causing borderless.Thread pool performance testing and verification results show that thread pool takes a more excellent concurrency control strategy and has provided the stable throughput for the server.
multi-threading;thread pool;thread pool size;server
2016-06-02
2016-09-15 網(wǎng)絡(luò)出版時(shí)間:2017-06-05
國(guó)家自然科學(xué)基金資助項(xiàng)目(61271234)
吉 利(1990-),男,碩士,研究方向?yàn)樾l(wèi)星通信技術(shù)。
http://kns.cnki.net/kcms/detail/61.1450.TP.20170605.1506.024.html
TP39
A
1673-629X(2017)08-0149-03
10.3969/j.issn.1673-629X.2017.08.031