qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          HTTP負(fù)載測(cè)試

          有很多人在談?wù)揌TTP服務(wù)器軟件的性能測(cè)試,也許是因?yàn)楝F(xiàn)在有太多的服務(wù)器選擇。

            這很好,但是我看到有人很多基本相同的問(wèn)題,使得測(cè)試結(jié)果的推論值得懷疑。在日常工作中花費(fèi)了很多時(shí)間在高性能代理緩存和源站性能測(cè)試方面之后,這里有我認(rèn)為比較重要的一些方面來(lái)分享。

            希望能拋磚引玉。

            0、一致性

            最最重要的是,每次都測(cè)試同一個(gè)時(shí)間點(diǎn)。因?yàn)橄到y(tǒng)發(fā)生的每個(gè)改變,無(wú)論是OS升級(jí)還是運(yùn)行了其它消耗帶寬和CPU的應(yīng)用,都會(huì)影響測(cè)試的結(jié)果,所以一定要把測(cè)試環(huán)境固定下來(lái)。

            也許,有人會(huì)說(shuō)那就把測(cè)試放虛擬機(jī)里做吧,聽(tīng)起來(lái)不錯(cuò)。但是,這種方式加多了一個(gè)抽象層(而且宿主機(jī)上也跑了更多的進(jìn)程),如果說(shuō)這樣就能得到更加一致的結(jié)果,我是無(wú)論如何也不會(huì)相信的。我覺(jué)得,最好的辦法是為測(cè)試準(zhǔn)備一套專用硬件。如果做不到這個(gè),那么一定要把所有測(cè)試放在同一個(gè)會(huì)話里,不要去比較不同會(huì)話里的測(cè)試結(jié)果。

            1、每臺(tái)機(jī)器,各司其職

            人們常常會(huì)犯另一個(gè)錯(cuò)誤,他們把負(fù)載生成器和被測(cè)試的服務(wù)器放在同一臺(tái)機(jī)器上。這樣做將導(dǎo)致產(chǎn)生不可靠的測(cè)試結(jié)果,因?yàn)椋?fù)載生成器實(shí)際上是「竊取」了一部分資源,而且這部分資源的量還會(huì)隨著服務(wù)器處理負(fù)載情況的變化而變化。

            最好的做法是,為測(cè)試主體和負(fù)載生成器分配不同的硬件,而且將它們放在封閉的網(wǎng)絡(luò)上。這樣做的代價(jià)并不是太高,我們并不需要非常高精尖的配置,只需要確保一致性就好。

            所以,如果有人跟你說(shuō),他們的測(cè)試是在localhost上做的,或者拒絕透露測(cè)試用了幾臺(tái)機(jī)器,那么你盡可以忽略他們的結(jié)果。因?yàn)椋@樣的結(jié)果,往好了說(shuō),只有最基本的定性作用,往壞了說(shuō),甚至可能會(huì)誤人子弟。

            2、檢查網(wǎng)絡(luò)

            在測(cè)試前,一定要知道你的網(wǎng)絡(luò)有多大容量,這樣,你才會(huì)知道,什么時(shí)候是你測(cè)試的服務(wù)器制約了測(cè)試,什么時(shí)候是網(wǎng)絡(luò)制約了測(cè)試。

            一種方法是通過(guò)iperf:

          qa1:~> iperf -c qa2 ------------------------------------------------------------ Client connecting to qa2, TCP port 5001 TCP window size: 16.0 KByte (default) ------------------------------------------------------------ [  3] local 192.168.1.106 port 56014 connected with 192.168.1.107 port 5001 [ ID] Interval       Transfer     Bandwidth [  3]  0.0-10.0 sec  1.10 GBytes   943 Mbits/sec

            從上面的輸出中可以看到,我的千兆網(wǎng)可以達(dá)到943Mbps的速度(之所以不到1000Mbps,是由于TCP的開(kāi)銷)。

            知道網(wǎng)絡(luò)容量后,我們需要確保它不會(huì)成為制約測(cè)試的因素。有幾種方法,最簡(jiǎn)單的是記錄當(dāng)前使用的帶寬。例如,httperf可以像這樣展示當(dāng)前的帶寬用量:

          Net I/O: 23399.7 KB/s (191.7*10^6 bps)

            上例表明,我們目前只用了192Mbps。

            記住,我們?cè)谪?fù)載產(chǎn)生工具中看到的數(shù)字并沒(méi)有包括TCP開(kāi)銷,而且,如果我們的負(fù)載在整個(gè)測(cè)試期間并不固定,那么突發(fā)帶寬一定會(huì)有超過(guò)平均值的時(shí)候。而且除了帶寬以外還有其它的問(wèn)題,例如,廉價(jià)的網(wǎng)卡和交換機(jī)很有可能會(huì)被大量的數(shù)據(jù)包淹沒(méi)。

            基于以上的種種原因,我們最好不要讓測(cè)試的帶寬逼近網(wǎng)絡(luò)的可用帶寬,最好是不要超過(guò)某個(gè)比例,比如2/3。對(duì)網(wǎng)絡(luò)(包括網(wǎng)卡和交換機(jī))錯(cuò)誤和峰值速率進(jìn)行監(jiān)控也是一個(gè)很好的辦法。

          3、去除OS限制

            同樣,我們還需要確保OS不會(huì)對(duì)服務(wù)器的表現(xiàn)構(gòu)成限制。

            TCP參數(shù)的調(diào)整頗為重要,但它會(huì)對(duì)所有測(cè)試主體產(chǎn)生相同的影響。更為重要的是,不要讓你測(cè)試的服務(wù)器用光文件描述符(file descriptor)。

            4、避免壓測(cè)客戶端

            現(xiàn)代高性能服務(wù)器使得容易將負(fù)載產(chǎn)生器的限制當(dāng)作服務(wù)器的能力。所以,認(rèn)真檢查以確保你的客戶端沒(méi)有用爆CPU,如果有任何懷疑,就使用更多客戶端壓力來(lái)驗(yàn)證(autobench可以讓這件事更簡(jiǎn)單)。

            確保負(fù)載產(chǎn)生器的硬件優(yōu)于要測(cè)試的服務(wù)端硬件,也很有幫助;比如,使用4核心的i5-750服務(wù)器產(chǎn)生負(fù)載,將服務(wù)器運(yùn)行在較慢的雙核i3-350服務(wù)器上,而且經(jīng)常只用兩個(gè)核心之一。

            另外一個(gè)需要注意的因素是客戶端錯(cuò)誤,尤其是臨時(shí)端口(ephemeral ports)用盡。處理這個(gè)問(wèn)題有很多策略,擴(kuò)大服務(wù)器的可用端口范圍,或設(shè)置多個(gè)網(wǎng)絡(luò)接口,確認(rèn)由客戶端使用它們(有時(shí)需要一些技巧)。也可以優(yōu)化TIME_WAIT時(shí)間(只有是測(cè)試環(huán)境就沒(méi)問(wèn)題),或僅僅使用HTTP長(zhǎng)連接和激進(jìn)的客戶端超時(shí)策略,確保連接速率不會(huì)用盡端口數(shù)。

            我喜歡httperf的一個(gè)原因是它在結(jié)束時(shí)提供了錯(cuò)誤的概要:

          Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
          Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

            這里,服務(wù)器的問(wèn)題位于第一行(比如由于服務(wù)器端超過(guò)--timeout設(shè)置的超時(shí)時(shí)間而造成的請(qǐng)求超時(shí),或拒絕連接,或連接重置),客戶端錯(cuò)誤(如文件描述符用盡或地址用盡)在第二行。

            在測(cè)試本身出錯(cuò)時(shí),這能夠幫你及時(shí)了解。

            5、過(guò)載時(shí)的容量并不是真正的容量

            產(chǎn)生盡可能大的負(fù)載,扔給服務(wù)器,這是許多負(fù)載產(chǎn)生工具的工作模式。

            這種方法對(duì)于檢查服務(wù)器在過(guò)載情況下的表現(xiàn)也許不錯(cuò),但它并不能真正幫我們確定服務(wù)器的容量。因?yàn)椋S多服務(wù)器在過(guò)載的情況下都會(huì)損失一部分的容量。

            更好的方法是逐步加大負(fù)載,直到服務(wù)器達(dá)到容量上限,出現(xiàn)性能下降為止。我們可以把結(jié)果繪制成一條先抵達(dá)峰值、隨后下降的曲線,而下降的程度意味著服務(wù)器應(yīng)對(duì)過(guò)載時(shí)的表現(xiàn)情況。

            autobench是其中的一種方法,我們可以設(shè)置測(cè)試的范圍,然后就可以得到這樣一張圖:

            可以看到,在響應(yīng)消息最小時(shí),服務(wù)器的處理峰值為16,000響應(yīng)/秒,但在過(guò)載情況下快速衰落至14,000響應(yīng)/秒。而在響應(yīng)消息更大時(shí),過(guò)載情況下的衰落并沒(méi)有這么多,但可以看到錯(cuò)誤條不停彈出來(lái),說(shuō)明了服務(wù)器的緊張境況。

          6、30秒的測(cè)試不算測(cè)試

            由于處于應(yīng)用、OS與網(wǎng)絡(luò)棧各層的緩沖區(qū)需要一定的穩(wěn)定時(shí)間,所以30秒的測(cè)試很可能不準(zhǔn)確。如果你的測(cè)試數(shù)據(jù)是要正式發(fā)布的,請(qǐng)至少測(cè)試3分鐘,或者更長(zhǎng)一些,比如5到10分鐘。

            7、不要僅僅測(cè)試Hello World

            如果要測(cè)試服務(wù)器的響應(yīng)是否迅速,用4字節(jié)的響應(yīng)消息過(guò)于局限,意義不大,4k甚至100k才更有現(xiàn)實(shí)意義。

            另外一個(gè)需要測(cè)試的是服務(wù)器在面對(duì)大量空閑連接時(shí)的表現(xiàn),比如10,000個(gè)連接。這對(duì)現(xiàn)代的成熟服務(wù)器來(lái)說(shuō)本來(lái)不算什么,但往往會(huì)導(dǎo)致一些你想象不到的問(wèn)題。

            當(dāng)然,以上僅僅只是兩個(gè)例子而已。

            8、僅僅平均值是不夠的

            如果有人告訴你,服務(wù)器可以每秒產(chǎn)生1000個(gè)響應(yīng),平均時(shí)延為5ms,聽(tīng)起來(lái)是不是很棒?但是,如果這1000個(gè)響應(yīng)里,有些需要100ms呢?或者,如果說(shuō)在整個(gè)測(cè)試的10%時(shí)間里,由于垃圾收集的關(guān)系,只能達(dá)到500個(gè)響應(yīng)/秒的速度,你怎么看?

            平均值是個(gè)快速指標(biāo),但是,僅此而已。有許多重要的信息,包含在時(shí)間線和直方圖(histogram)中,但平均值并沒(méi)有提供。如果你的測(cè)試工具不提供時(shí)間線和直方圖,那么還是換一個(gè)吧(開(kāi)源的話,還可以選擇提交一個(gè)patch)。

            httperf可以顯示:

          Total: connections 180000 requests 180000 replies 180000 test-duration 179.901 s

          Connection rate: 1000.0 conn/s (99.9 ms/conn, <=2 concurrent connections)
          Connection time [ms]: min 0.4 avg 0.5 max 12.9 median 0.5 stddev 0.4
          Connection time [ms]: connect 0.1
          Connection length [replies/conn]: 1.000

          Request rate: 1000.0 req/s (.9 ms/req)
          Request size [B]: 79.0

          Reply rate [replies/s]: min 999.1 avg 1000.0 max 1000.2 stddev 0.1 (35 samples)
          Reply time [ms]: response 0.4 transfer 0.0
          Reply size [B]: header 385.0 content 1176.0 footer 0.0 (total 1561.0)
          Reply status: 1xx=0 2xx=0 3xx=0 4xx=1800 5xx=0

            可以看到,它不僅顯示了響應(yīng)速度的平均值,還顯示了最小值、最大值和標(biāo)準(zhǔn)差(deviation)。連接時(shí)間也是這樣。

            9、把相關(guān)信息全部發(fā)布出來(lái)

            如果只是給出一個(gè)結(jié)果,而不給出重現(xiàn)它的必要信息,那么往好了說(shuō),這個(gè)結(jié)果只是一個(gè)全憑大家靠信仰來(lái)相信的沒(méi)有用的結(jié)論,往壞了說(shuō),它甚至有故意誤人子弟之嫌(譯者注:各種數(shù)據(jù)庫(kù)的宣傳式的benchmark表示紛紛中槍)。所以,如果要發(fā)布測(cè)試結(jié)果,記得要把測(cè)試的相關(guān)上下文也一起發(fā)布,不光是測(cè)試所用的硬件,還應(yīng)包括OS版本與配置、網(wǎng)絡(luò)設(shè)置、服務(wù)器與負(fù)載產(chǎn)生器的版本與配置、所用的負(fù)載,甚至必要時(shí)還要加上源代碼。

            理想情況下,我們可以采用代碼庫(kù)(比如github)的形式,使任何人都能以最小的代價(jià)(用自己的硬件)重現(xiàn)你的結(jié)果。

            10、嘗試不同工具

            看到這里,你也許會(huì)以為我只認(rèn)httperf和autobench這兩個(gè)工具。我很喜歡全能型選手,可惜httperf不是。對(duì)于現(xiàn)代的一些服務(wù)器來(lái)說(shuō),httperf太慢了,也許是由于它缺乏事件循環(huán)的緣故。httperf只能以每秒50到500個(gè)請(qǐng)求的速度測(cè)試一些PHP應(yīng)用,但無(wú)論如何也做不到以每秒上萬(wàn)個(gè)請(qǐng)求的速度去測(cè)試那些現(xiàn)代的web服務(wù)器。

            而且,如果只認(rèn)準(zhǔn)一個(gè)工具的話,可能會(huì)由于客戶端與服務(wù)器之間一些奇怪的交互,導(dǎo)致對(duì)某個(gè)實(shí)現(xiàn)特別不利的情況發(fā)生。例如,有些工具建立持久連接的方式對(duì)一些服務(wù)器不夠友好,導(dǎo)致它們的測(cè)試結(jié)果不佳。

            而我之所以喜歡httperf,上文中也已經(jīng)提過(guò),由于它有很詳細(xì)的統(tǒng)計(jì)信息和錯(cuò)誤報(bào)告,而且可以自定義負(fù)載速率,讓我們可以更清晰地了解我們的服務(wù)器。我希望其它工具也能輸出同樣詳細(xì)的信息。

            我最近還用了siege,雖然在信息方面還比不上httperf那么詳細(xì),不過(guò)也很好用,尤其速度真叫一個(gè)快。

            原文鏈接:http://www.oschina.net/translate/http_benchmark_rules

          posted on 2013-05-03 10:34 順其自然EVO 閱讀(267) 評(píng)論(0)  編輯  收藏 所屬分類: web 前端性能測(cè)試

          <2013年5月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 隆昌县| 岚皋县| 宜州市| 乐安县| 博乐市| 贡山| 巨野县| 五寨县| 佳木斯市| 德钦县| 枣阳市| 永泰县| 从江县| 腾冲县| 怀仁县| 花莲县| 大兴区| 木兰县| 灵石县| 华池县| 谢通门县| 咸阳市| 景德镇市| 随州市| 灵石县| 民勤县| 贵港市| 礼泉县| 阿拉善盟| 黄大仙区| 邢台市| 丽江市| 酉阳| 灵山县| 陵水| 迁西县| 公主岭市| 沂源县| 昌宁县| 阿瓦提县| 平潭县|