Author:放翁(文初)
Date: 2010/4/14
Email:fangweng@taobao.com
圍脖: http://t.sina.com.cn/fangweng
這部分是結(jié)果,大家可以當(dāng)看倒序的電影,后續(xù)會(huì)有前篇給出。
Web服務(wù)異步化:
包括兩部分,數(shù)據(jù)傳輸層異步化(大家已經(jīng)熟知的NIO),Http業(yè)務(wù)請(qǐng)求異步化(continuations,servlet3.0)。服務(wù)異步處理我將會(huì)有一個(gè)詳細(xì)的說明文檔(服務(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)單的說一下服務(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)話短說,上測(cè)試結(jié)果……
環(huán)境說明:
Linux 2.6.9-55.ELsmp
4 Core
4 G Memory
JDK 1.6.0_07
測(cè)試工具:loadRunner 9.5
測(cè)試涉及到了四種容器部署:后面都會(huì)用縮寫在測(cè)試結(jié)果上注明
1. Apache + modjk + Jboss(后面縮寫為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ù)是通過應(yīng)用自身實(shí)現(xiàn),具體代碼可以參考后面的代碼附件。
測(cè)試結(jié)果如下:
場(chǎng)景1:500 并發(fā)用戶場(chǎng)景下,后端服務(wù)一次請(qǐng)求消耗3秒鐘
容器 |
模式 |
TPS |
Average Response Time(s) |
Average Throughput(byte/s) |
最大請(qǐng)求處理數(shù) |
Success rate |
Jetty7 |
asyn(resume) |
162.8 |
3.008 |
38430 |
500 |
100% |
Tomcat6 |
syn |
163.3 |
3.005 |
18453 |
500 |
100% |
這個(gè)場(chǎng)景測(cè)試的目的是比較在線程池資源足夠的時(shí)候,異步和同步的差別。(也就是TOP服務(wù)器所有的資源處于正常服務(wù),前臺(tái)請(qǐng)求沒有因?yàn)榍岸芜B接被消耗完,導(dǎo)致服務(wù)質(zhì)量降低)
可以看到,在TPS和Response Time上兩者基本上沒有太大差別,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秒鐘
容器 |
模式 |
TPS |
Average Response Time(s) |
Average Throughput(byte/s) |
最大請(qǐng)求處理數(shù) |
Success rate |
Jetty7 |
asyn(resume) |
317.06 |
3.036 |
74826 |
1000 |
100% |
Tomcat6 |
syn |
163.323 |
5.904 |
18455 |
500 |
100% |
場(chǎng)景2就在資源不足的情況下,比較異步服務(wù)請(qǐng)求與同步請(qǐng)求處理能力。(例如由于后端某些服務(wù)比較慢,導(dǎo)致前段的服務(wù)器能夠承載的請(qǐng)求數(shù)目超過了線程數(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秒鐘
容器 |
模式 |
TPS |
Average Response Time(s) |
Average Throughput(byte/s) |
Server Load |
Success rate |
Jboss |
syn |
75.546 |
5.347 |
21002 |
0.115 |
68% |
Jetty7 |
Syn |
163.156 |
8.788 |
19252 |
0.129 |
100% |
Jetty7 |
Asyn(complete) |
432.153 |
3.312 |
76491 |
2.649 |
100% |
Jetty7 |
Asyn(resume) |
423.638 |
3.375 |
99979 |
2.826 |
100% |
Tomcat6 |
Syn |
163.836 |
8.75 |
18513 |
0.258 |
100% |
Tomcat7 |
ASyn |
423.501 |
3.328 |
54632 |
1.064 |
99.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é)果很類似,但是load方面jetty7更好。
3. 異步處理方面Jetty7的兩種方式基本上差別不大(后續(xù)還需要深入源碼看看對(duì)于數(shù)據(jù)緩存資源復(fù)用的狀況),Tomcat7的異步處理成功率有些問題(錯(cuò)誤多半是在獲取response回寫的時(shí)候,response已經(jīng)被提前釋放,看來(lái)Tomcat7還是需要一些時(shí)間來(lái)考驗(yàn)),load上來(lái)說tomcat結(jié)果比較好。
4. 異步請(qǐng)求在提高處理能力的情況下,對(duì)于資源消耗也較大(線程切換較為頻繁),不過還是在承受范圍。
三個(gè)場(chǎng)景組合比較:
容器 |
并發(fā)用戶 |
模式 |
TPS |
Average Response Time(s) |
Average Throughput(byte/s) |
Success rate |
Jetty7 |
500 |
asyn(resume) |
162.8 |
3.008 |
38430 |
100% |
Jetty7 |
1000 |
asyn(resume) |
317.06 |
3.036 |
74826 |
100% |
Jetty7 |
1500 |
asyn(resume) |
423.638 |
3.375 |
99979 |
100% |
Tomcat6 |
500 |
syn |
163.3 |
3.005 |
18453 |
100% |
Tomcat6 |
1000 |
syn |
163.323 |
5.904 |
18455 |
100% |
Tomcat6 |
1500 |
Syn |
163.836 |
8.75 |
18513 |
100% |
最后將三個(gè)場(chǎng)景合并起來(lái)做一個(gè)簡(jiǎn)單的比較,得到信息如下:
1. 隨著并發(fā)用戶的增加,本身異步處理也會(huì)有衰減,同時(shí)對(duì)于性能消耗(線程切換)也會(huì)不斷增長(zhǎng)。
2. 異步化在消息頭上會(huì)增加一些數(shù)據(jù),會(huì)增加回寫的帶寬消耗(不過量不大),一個(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)化可以通過擴(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. 代碼遷移成本。
后續(xù)篇涉及:服務(wù)異步化的概念,服務(wù)異步化的幾種標(biāo)準(zhǔn)實(shí)現(xiàn),服務(wù)異步化容器的特點(diǎn)和實(shí)現(xiàn),現(xiàn)有容器可優(yōu)化的點(diǎn)。
打個(gè)廣告:http://blog.open.taobao.com/archives/1417 TOP需要人才加入