Web服務(wù)請(qǐng)求異步化測(cè)試
Web服務(wù)異步化:
包括兩部分,數(shù)據(jù)傳輸層異步化(大家已經(jīng)熟知的NIO),Http業(yè)務(wù)請(qǐng)求異步化(continuations,servlet3.0)。服務(wù)異步處理我將會(huì)有一個(gè)詳細(xì)的說(shuō)明文檔(服務(wù)異步化的概念,服務(wù)異步化的幾種標(biāo)準(zhǔn)實(shí)現(xiàn),服務(wù)異步化容器的特點(diǎn)),后續(xù)給出。
Web服務(wù)異步化測(cè)試原因:
TOP應(yīng)用特殊性:
1.自身服務(wù)能力由后端的服務(wù)能力決定。(對(duì)同步Web請(qǐng)求的轉(zhuǎn)發(fā))
2.后端服務(wù)部署等同性,但要求服務(wù)互不影響。
第一點(diǎn)導(dǎo)致TOP無(wú)法預(yù)估自身服務(wù)能力(不同后端服務(wù)處理速度下的TOP有不一樣的支持能力),同時(shí)也無(wú)法應(yīng)對(duì)在后端服務(wù)異常的情況下,整體的服務(wù)質(zhì)量。
第二點(diǎn)導(dǎo)致TOP只有在物理上分隔不同服務(wù)提供者所對(duì)應(yīng)的TOP集群(資源浪費(fèi),同時(shí)無(wú)法動(dòng)態(tài)調(diào)整資源來(lái)滿足服務(wù)變化情況)。
因此需要對(duì)TOP實(shí)施web服務(wù)異步處理的測(cè)試。這里簡(jiǎn)單的說(shuō)一下服務(wù)異步化的使用場(chǎng)景需要滿足的幾個(gè)特點(diǎn):
1. 處理耗時(shí)大多消耗在于對(duì)后端或者外部服務(wù)資源的請(qǐng)求上。
2. 后端或者外部資源在更多的流量下不會(huì)成為瓶頸。
拿TOP來(lái)解釋一下:TOP自身處理主要包括路由,安全,流控等,但是最耗時(shí)的是在請(qǐng)求后端各個(gè)淘寶團(tuán)隊(duì)的服務(wù)。其次當(dāng)前后端服務(wù)能力尚未達(dá)到真實(shí)的處理高峰,因此很多請(qǐng)求被堵在TOP平臺(tái),特別是當(dāng)某些服務(wù)異常的時(shí)候,另一些服務(wù)就會(huì)被拖累無(wú)法得到充分利用。(當(dāng)然我們有流控,發(fā)現(xiàn)后端服務(wù)能力已經(jīng)成為瓶頸的時(shí)候可以對(duì)單獨(dú)服務(wù)作限制)。
長(zhǎng)話短說(shuō),上測(cè)試結(jié)果……
環(huán)境說(shuō)明:
Linux 2.6.9-55.ELsmp
4 Core
4 G Memory
JDK 1.6.0_07
測(cè)試工具:loadRunner 9.5
測(cè)試涉及到了四種容器部署:后面都會(huì)用縮寫(xiě)在測(cè)試結(jié)果上注明
1. Apache + modjk + Jboss(后面縮寫(xiě)為Jboss):
此模式Apache配置如下:
<IfModule mpm_worker_module> ServerLimit 80 ThreadLimit 128 StartServers 10 MaxClients 10240 MinSpareThreads 64 MaxSpareThreads 800 ThreadsPerChild 128 MaxRequestsPerChild 10000 </IfModule> |
Jboss的web容器配置如下:
<Connector port="8009" address="${jboss.bind.address}" connectionTimeout="8000" protocol="AJP/1.3" maxThreads="500" minSpareThreads="40" maxSpareThreads="75" maxPostSize="512000" acceptCount="300" bufferSize="16384" emptySessionPath="false" enableLookups="false" redirectPort="8443" URIEncoding="utf-8"/>
Jboss的web部分以APR模式啟動(dòng)。
2. Tomcat6(APR)
關(guān)鍵配置如下:
<Executor name="topThreadPool" namePrefix="top-exec-"
maxThreads="500" minSpareThreads="40"/>
<Connector port="7777" protocol="HTTP/1.1"
executor="topThreadPool" connectionTimeout="20000" acceptCount="1000"
redirectPort="8444" />
3. Tomcat7 RC 4(APR)
關(guān)鍵配置如下:
<Executor name="topThreadPool" namePrefix="top-exec-"
maxThreads="500" minSpareThreads="4"/>
<Connector executor="topThreadPool" port="3333" protocol="HTTP/1.1"
connectionTimeout="20000" acceptCount="1000"
redirectPort="6443" />
4. Jetty7
關(guān)鍵配置如下:
<Set name="ThreadPool"> <!-- Default queued blocking threadpool --> <New class="org.eclipse.jetty.util.thread.QueuedThreadPool"> <Set name="minThreads">10</Set> <Set name="maxThreads">500</Set> </Set> <Call name="addConnector"> <Arg> <New class="org.eclipse.jetty.server.nio.SelectChannelConnector"> <Set name="host"><SystemProperty name="jetty.host" /></Set> <Set name="port"><SystemProperty name="jetty.port" default="6060"/></Set> <Set name="maxIdleTime">300000</Set> <Set name="Acceptors">2</Set> <Set name="statsOn">false</Set> <Set name="confidentialPort">8443</Set> <Set name="lowResourcesConnections">20000</Set> <Set name="lowResourcesMaxIdleTime">5000</Set> </New> </Arg> </Call> |
附注:
Asyn表示異步模式,syn表示同步。Asyn中還分成resume和complete兩種方式,后續(xù)在介紹技術(shù)背景的時(shí)候詳細(xì)描述。
對(duì)于服務(wù)端的load不是每一個(gè)測(cè)試都做了記錄,選取了最全面的1500并發(fā)用戶做了測(cè)試。
最大服務(wù)請(qǐng)求處理數(shù)是通過(guò)應(yīng)用自身實(shí)現(xiàn),具體代碼可以參考后面的代碼附件。
測(cè)試結(jié)果如下:
場(chǎng)景1:500 并發(fā)用戶場(chǎng)景下,后端服務(wù)一次請(qǐng)求消耗3秒鐘
這個(gè)場(chǎng)景測(cè)試的目的是比較在線程池資源足夠的時(shí)候,異步和同步的差別。(也就是TOP服務(wù)器所有的資源處于正常服務(wù),前臺(tái)請(qǐng)求沒(méi)有因?yàn)榍岸芜B接被消耗完,導(dǎo)致服務(wù)質(zhì)量降低)
可以看到,在TPS和Response Time上兩者基本上沒(méi)有太大差別,TPS就等于500/3=167左右(3秒一個(gè)請(qǐng)求,因此用這種簡(jiǎn)單算式可以算出),響應(yīng)時(shí)間也較為正常。當(dāng)時(shí)我發(fā)現(xiàn)在每秒吞吐量上有些差別,后來(lái)單個(gè)測(cè)試case跑了一下,發(fā)現(xiàn)是返回的http header比較大,應(yīng)該是在做異步化時(shí)重入等作的一些標(biāo)識(shí)(后面其他容器的異步化也是一樣)。
最大處理請(qǐng)求數(shù)都在服務(wù)端后臺(tái)看到是500,等同于最大的并發(fā)用戶數(shù)。
場(chǎng)景2:1000 并發(fā)用戶場(chǎng)景下,后端服務(wù)一次請(qǐng)求消耗3秒鐘
場(chǎng)景2就在資源不足的情況下,比較異步服務(wù)請(qǐng)求與同步請(qǐng)求處理能力。(例如由于后端某些服務(wù)比較慢,導(dǎo)致前段的服務(wù)器能夠承載的請(qǐng)求數(shù)目超過(guò)了線程數(shù))
這個(gè)場(chǎng)景的結(jié)果可以看到TPS在異步模式下與并發(fā)用戶數(shù)呈現(xiàn)同步增長(zhǎng),就好比配置了1000個(gè)線程作為線程池一樣,同樣在后端打出的最大請(qǐng)求數(shù)上也證明了這一點(diǎn),因此前段線程池的服務(wù)能力在異步的情況下充分復(fù)用(當(dāng)然這里使用的異步服務(wù)處理使用的是NIO而不是BIO的Connector)。同樣在吞吐量上依然是增加的,由于異步附加的內(nèi)容。
場(chǎng)景3:1500 并發(fā)用戶場(chǎng)景下,后端服務(wù)一次請(qǐng)求消耗3秒鐘
場(chǎng)景三比對(duì)了現(xiàn)有TOP的部署模式(Apache + modjk + Jboss)和Jetty7的同步模式,兩種異步模式,Tomcat同步模式,Tomcat的servlet3.0異步模式的處理情況。根據(jù)測(cè)試可以得到的信息如下:
1. 現(xiàn)有部署方式在后端服務(wù)處理耗時(shí)較大的情況下,處理能力不如Jetty7和Tomcat6,同時(shí)出錯(cuò)率很高。
2. Jetty7的同步處理測(cè)試結(jié)果和Tomcat6的同步處理測(cè)試結(jié)果很類(lèi)似,但是load方面jetty7更好。
3. 異步處理方面Jetty7的兩種方式基本上差別不大(后續(xù)還需要深入源碼看看對(duì)于數(shù)據(jù)緩存資源復(fù)用的狀況),Tomcat7的異步處理成功率有些問(wèn)題(錯(cuò)誤多半是在獲取response回寫(xiě)的時(shí)候,response已經(jīng)被提前釋放,看來(lái)Tomcat7還是需要一些時(shí)間來(lái)考驗(yàn)),load上來(lái)說(shuō)tomcat結(jié)果比較好。
4. 異步請(qǐng)求在提高處理能力的情況下,對(duì)于資源消耗也較大(線程切換較為頻繁),不過(guò)還是在承受范圍。
三個(gè)場(chǎng)景組合比較:
最后將三個(gè)場(chǎng)景合并起來(lái)做一個(gè)簡(jiǎn)單的比較,得到信息如下:
1. 隨著并發(fā)用戶的增加,本身異步處理也會(huì)有衰減,同時(shí)對(duì)于性能消耗(線程切換)也會(huì)不斷增長(zhǎng)。
2. 異步化在消息頭上會(huì)增加一些數(shù)據(jù),會(huì)增加回寫(xiě)的帶寬消耗(不過(guò)量不大),一個(gè)請(qǐng)求增加了100byte左右的消息數(shù)據(jù)。
測(cè)試總結(jié):
1. Web請(qǐng)求異步化在TOP很合適。
重復(fù)兩個(gè)條件:
a. 處理耗時(shí)大多消耗在于對(duì)后端或者外部服務(wù)資源的請(qǐng)求上。
b. 后端或者外部資源在更多的流量下不會(huì)成為瓶頸。
2. Web請(qǐng)求異步化在Jetty6到7上已經(jīng)經(jīng)歷了2年多的成長(zhǎng)(Google App Engine , Yahoo Hadoop),穩(wěn)定性和效率較好。(同時(shí)很多優(yōu)化可以通過(guò)擴(kuò)展自行定制,jetty的可擴(kuò)展性很好)Tomcat7在servlet3上處于剛發(fā)布階段,還有待繼續(xù)完善。(Servlet3的另一種模式尚未執(zhí)行成功,直接導(dǎo)致jvm退出)
后續(xù)需要繼續(xù)跟進(jìn)的:
1. 對(duì)于大數(shù)據(jù)量請(qǐng)求的容器間性能對(duì)比。(圖片上傳或者大數(shù)據(jù)量的Post請(qǐng)求)
2. 容器安全性。(是否容易被攻擊)
3. 代碼遷移成本。
posted on 2014-08-18 09:39 順其自然EVO 閱讀(489) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): 測(cè)試學(xué)習(xí)專(zhuān)欄 、web 前端性能測(cè)試