




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第Go標(biāo)準(zhǔn)庫http與fasthttp服務(wù)端性能對(duì)比場景分析目錄1.背景2.性能測試3.對(duì)結(jié)果的簡要分析4.優(yōu)化途徑
1.背景
Go初學(xué)者學(xué)習(xí)Go時(shí),在編寫了經(jīng)典的hello,world程序之后,可能會(huì)迫不及待的體驗(yàn)一下Go強(qiáng)大的標(biāo)準(zhǔn)庫,比如:用幾行代碼寫一個(gè)像下面示例這樣擁有完整功能的webserver:
//來自/pkg/net/http/#example_ListenAndServe
packagemain
import(
"io"
"log"
"net/http"
funcmain(){
helloHandler:=func(whttp.ResponseWriter,req*http.Request){
io.WriteString(w,"Hello,world!\n")
http.HandleFunc("/hello",helloHandler)
log.Fatal(http.ListenAndServe(":8080",nil))
}
gonet/http包是一個(gè)比較均衡的通用實(shí)現(xiàn),能滿足大多數(shù)gopher90%以上場景的需要,并且具有如下優(yōu)點(diǎn):
標(biāo)準(zhǔn)庫包,無需引入任何第三方依賴;對(duì)http規(guī)范的滿足度較好;無需做任何優(yōu)化,即可獲得相對(duì)較高的性能;支持HTTP代理;支持HTTPS;無縫支持HTTP/2。
不過也正是因?yàn)閔ttp包的均衡通用實(shí)現(xiàn),在一些對(duì)性能要求嚴(yán)格的領(lǐng)域,net/http的性能可能無法勝任,也沒有太多的調(diào)優(yōu)空間。這時(shí)我們會(huì)將眼光轉(zhuǎn)移到其他第三方的http服務(wù)端框架實(shí)現(xiàn)上。
而在第三方http服務(wù)端框架中,一個(gè)行如其名的框架fasthttp被提及和采納的較多,fasthttp官網(wǎng)宣稱其性能是net/http的十倍(基于gotestbenchmark的測試結(jié)果)。
fasthttp采用了許多性能優(yōu)化上的最佳實(shí)踐,尤其是在內(nèi)存對(duì)象的重用上,大量使用sync.Pool以降低對(duì)GoGC的壓力。
那么在真實(shí)環(huán)境中,到底fasthttp能比net/http快多少呢?恰好手里有兩臺(tái)性能還不錯(cuò)的服務(wù)器可用,在本文中我們就在這個(gè)真實(shí)環(huán)境下看看他們的實(shí)際性能。
2.性能測試
我們分別用net/http和fasthttp實(shí)現(xiàn)兩個(gè)幾乎零業(yè)務(wù)的被測程序:
nethttp:
///bigwhite/experiments/blob/master/http-benchmark/nethttp/main.go
packagemain
import(
_"expvar"
"log"
"net/http"
_"net/http/pprof"
"runtime"
"time"
funcmain(){
gofunc(){
for{
log.Println("當(dāng)前routine數(shù)量:",runtime.NumGoroutine())
time.Sleep(time.Second)
http.Handle("/",http.HandlerFunc(func(whttp.ResponseWriter,r*http.Request){
w.Write([]byte("Hello,Go!"))
log.Fatal(http.ListenAndServe(":8080",nil))
}
fasthttp:
///bigwhite/experiments/blob/master/http-benchmark/fasthttp/main.go
packagemain
import(
"fmt"
"log"
"net/http"
"runtime"
"time"
_"expvar"
_"net/http/pprof"
"/valyala/fasthttp"
typeHelloGoHandlerstruct{
funcfastHTTPHandler(ctx*fasthttp.RequestCtx){
fmt.Fprintln(ctx,"Hello,Go!")
funcmain(){
gofunc(){
http.ListenAndServe(":6060",nil)
gofunc(){
for{
log.Println("當(dāng)前routine數(shù)量:",runtime.NumGoroutine())
time.Sleep(time.Second)
s:=fasthttp.Server{
Handler:fastHTTPHandler,
s.ListenAndServe(":8081")
}
對(duì)被測目標(biāo)實(shí)施壓力測試的客戶端,我們基于hey這個(gè)http壓測工具進(jìn)行,為了方便調(diào)整壓力水平,我們將hey包裹在下面這個(gè)shell腳本中(僅適于在linux上運(yùn)行):
///bigwhite/experiments/blob/master/http-benchmark/client/http_client_load.sh
#./http_client_load.sh31000010GET81:8080
echo"$0task_numcount_per_heyconn_per_heymethodurl"
task_num=$1
count_per_hey=$2
conn_per_hey=$3
method=$4
url=$5
start=$(date+%s%N)
for((i=1;i=$task_num;i++));do{
tm=$(date+%T.%N)
echo"$tm:task$istart"
hey-n$count_per_hey-c$conn_per_hey-m$method$urlhey_$i.log
tm=$(date+%T.%N)
echo"$tm:task$idone"
}done
end=$(date+%s%N)
count=$(($task_num*$count_per_hey))
runtime_ns=$(($end-$start))
runtime=`echo"scale=2;$runtime_ns/1000000000"|bc`
echo"runtime:"$runtime
speed=`echo"scale=2;$count/$runtime"|bc`
echo"speed:"$speed
該腳本的執(zhí)行示例如下:
bashhttp_client_load.sh81000000200GET34:8080
http_client_load.shtask_numcount_per_heyconn_per_heymethodurl
16:58:09.146948690:task1start
16:58:09.147235080:task2start
16:58:09.147290430:task3start
16:58:09.147740230:task4start
16:58:09.147896010:task5start
16:58:09.148314900:task6start
16:58:09.148446030:task7start
16:58:09.148930840:task8start
16:58:45.001080740:task3done
16:58:45.241903500:task8done
16:58:45.261501940:task1done
16:58:50.032383770:task4done
16:58:50.985076450:task7done
16:58:51.269099430:task5done
16:58:52.008164010:task6done
16:58:52.166402430:task2done
runtime:43.02
speed:185960.01
從傳入的參數(shù)來看,該腳本并行啟動(dòng)了8個(gè)task(一個(gè)task啟動(dòng)一個(gè)hey),每個(gè)task向34:8080建立200個(gè)并發(fā)連接,并發(fā)送100whttpGET請(qǐng)求。
我們使用兩臺(tái)服務(wù)器分別放置被測目標(biāo)程序和壓力工具腳本:
目標(biāo)程序所在服務(wù)器:81(物理機(jī),Intelx86-64CPU,40核,128G內(nèi)存,CentOs7.6)
$cat/etc/redhat-release
CentOSLinuxrelease7.6.1810(Core)
$lscpu
Architecture:x86_64
CPUop-mode(s):32-bit,64-bit
ByteOrder:LittleEndian
CPU(s):40
On-lineCPU(s)list:0-39
Thread(s)percore:2
Core(s)persocket:10
NUMA節(jié)點(diǎn):2
廠商ID:GenuineIntel
CPU系列:6
型號(hào):85
型號(hào)名稱:Intel(R)Xeon(R)Silver4114CPU@2.20GHz
步進(jìn):4
CPUMHz:800.000
CPUmaxMHz:2201.0000
CPUminMHz:800.0000
BogoMIPS:4400.00
虛擬化:VT-x
L1d緩存:32K
L1i緩存:32K
L2緩存:1024K
L3緩存:14080K
NUMA節(jié)點(diǎn)0CPU:0-9,20-29
NUMA節(jié)點(diǎn)1CPU:10-19,30-39
Flags:fpuvmedepsetscmsrpaemcecx8apicsepmtrrpgemcacmovpatpse36clflushdtsacpimmxfxsrssesse2sshttmpbesyscallnxpdpe1gbrdtscplmconstant_tscartarch_perfmonpebsbtsrep_goodnoplxtopologynonstop_tscaperfmperfeagerfpupnipclmulqdqdtes64ds_cplvmxsmxesttm2ssse3sdbgfmacx16xtprpdcmpciddcasse4_1sse4_2x2apicmovbepopcnttsc_deadline_timeraesxsaveavxf16crdrandlahf_lmabm3dnowprefetchepbcat_l3cdp_l3intel_ptssbdmbaibrsibpbstibptpr_shadowvnmiflexpriorityeptvpidfsgsbasetsc_adjustbmi1hleavx2smepbmi2ermsinvpcidrtmcqmmpxrdt_aavx512favx512dqrdseedadxsmapclflushoptclwbavx512cdavx512bwavx512vlxsaveoptxsavecxgetbv1cqm_llccqm_occup_llccqm_mbm_totalcqm_mbm_localdthermidaaratplnptspkuospkespec_ctrlintel_stibpflush_l1d
壓力工具所在服務(wù)器:33(物理機(jī),鯤鵬arm64cpu,96核,80G內(nèi)存,CentOs7.9)
#cat/etc/redhat-release
CentOSLinuxrelease7.9.2009(AltArch)
#lscpu
Architecture:aarch64
ByteOrder:LittleEndian
CPU(s):96
On-lineCPU(s)list:0-95
Thread(s)percore:1
Core(s)persocket:48
NUMA節(jié)點(diǎn):4
型號(hào):0
CPUmaxMHz:2600.0000
CPUminMHz:200.0000
BogoMIPS:200.00
L1d緩存:64K
L1i緩存:64K
L2緩存:512K
L3緩存:49152K
NUMA節(jié)點(diǎn)0CPU:0-23
NUMA節(jié)點(diǎn)1CPU:24-47
NUMA節(jié)點(diǎn)2CPU:48-71
NUMA節(jié)點(diǎn)3CPU:72-95
Flags:fpasimdevtstrmaespmullsha1sha2crc32atomicsfphpasimdhpcpuidasimdrdmjscvtfcmadcpopasimddpasimdfhm
我用dstat監(jiān)控被測目標(biāo)所在主機(jī)資源占用情況(dstat-tcdngym),尤其是cpu負(fù)荷;通過[expvarmon監(jiān)控memstats],由于沒有業(yè)務(wù),內(nèi)存占用很少;通過gotoolpprof查看目標(biāo)程序中對(duì)各類資源消耗情況的排名。
下面是多次測試后制作的一個(gè)數(shù)據(jù)表格:
圖:測試數(shù)據(jù)
3.對(duì)結(jié)果的簡要分析
受特定場景、測試工具及腳本精確性以及壓力測試環(huán)境的影響,上面的測試結(jié)果有一定局限,但卻真實(shí)反映了被測目標(biāo)的性能趨勢。我們看到在給予同樣壓力的情況下,fasthttp并沒有10倍于nethttp的性能,甚至在這樣一個(gè)特定的場景下,兩倍于net/http的性能都沒有達(dá)到:我們看到在目標(biāo)主機(jī)cpu資源消耗接近70%的幾個(gè)用例中,fasthttp的性能僅比net/http高出30%~70%左右。
那么為什么fasthttp的性能未及預(yù)期呢?要回答這個(gè)問題,那就要看看net/http和fasthttp各自的實(shí)現(xiàn)原理了!我們先來看看net/http的工作原理示意圖:
圖:nethttp工作原理示意圖
http包作為server端的原理很簡單,那就是accept到一個(gè)連接(conn)之后,將這個(gè)conn甩給一個(gè)workergoroutine去處理,后者一直存在,直到該conn的生命周期結(jié)束:即連接關(guān)閉。
下面是fasthttp的工作原理示意圖:
圖:fasthttp工作原理示意圖
而fasthttp設(shè)計(jì)了一套機(jī)制,目的是盡量復(fù)用goroutine,而不是每次都創(chuàng)建新的goroutine。fasthttp的Serveraccept一個(gè)conn之后,會(huì)嘗試從workerpool中的ready切片中取出一個(gè)channel,該channel與某個(gè)workergoroutine一一對(duì)應(yīng)。一旦取出channel,就會(huì)將accept到的conn寫到該channel里,而channel另一端的workergoroutine就會(huì)處理該conn上的數(shù)據(jù)讀寫。當(dāng)處理完該conn后,該workergoroutine不會(huì)退出,而是會(huì)將自己對(duì)應(yīng)的那個(gè)channel重新放回workerpool中的ready切片中,等待這下一次被取出。
fasthttp的goroutine復(fù)用策略初衷很好,但在這里的測試場景下效果不明顯,從測試結(jié)果便可看得出來,在相同的客戶端并發(fā)和壓力下,net/http使用的goroutine數(shù)量與fasthttp相差無幾。這是由測試模型導(dǎo)致的:在我們這個(gè)測試中,每個(gè)task中的hey都會(huì)向被測目標(biāo)發(fā)起固定數(shù)量的[長連接(keep-alive)],然后在每條連接上發(fā)起飽和請(qǐng)求。這樣fasthttpworkerpool中的goroutine一旦接收到某個(gè)conn就只能在該conn上的通訊結(jié)束后才能重新放回,而該conn直到測試結(jié)束才會(huì)close,因此這樣的場景相當(dāng)于讓fasthttp退化成了net/http的模型,也染上了net/http的缺陷:goroutine的數(shù)量一旦多起來,goruntime自身調(diào)度所帶來的消耗便不可忽視甚至超過了業(yè)務(wù)處理所消耗的資源占比。下面分別是fasthttp在200長連接、8000長連接以及16000長連接下的cpuprofile的結(jié)果:
200長連接:
(pprof)top-cum
Showingnodesaccountingfor88.17s,55.35%of159.30stotal
Dropped150nodes(cum=0.80s)
Showingtop10nodesoutof60
flatflat%sum%cumcum%
0.46s0.29%0.29%101.46s63.69%/valyala/fasthttp.(*Server).serveConn
00%0.29%101.46s63.69%/valyala/fasthttp.(*workerPool).getCh.func1
00%0.29%101.46s63.69%/valyala/fasthttp.(*workerPool).workerFunc
0.04s0.025%0.31%89.46s56.16%internal/poll.ignoringEINTRIO(inline)
87.38s54.85%55.17%89.27s56.04%syscall.Syscall
0.12s0.075%55.24%60.39s37.91%bufio.(*Writer).Flush
00%55.24%60.22s37.80%net.(*conn).Write
0.08s0.05%55.29%60.21s37.80%net.(*netFD).Write
0.09s0.056%55.35%60.12s37.74%internal/poll.(*FD).Write
00%55.35%59.86s37.58%syscall.Write(inline)
(pprof)
8000長連接:
(pprof)top-cum
Showingnodesaccountingfor108.51s,54.46%of199.23stotal
Dropped204nodes(cum=1s)
Showingtop10nodesoutof66
flatflat%sum%cumcum%
00%0%119.11s59.79%/valyala/fasthttp.(*workerPool).getCh.func1
00%0%119.11s59.79%/valyala/fasthttp.(*workerPool).workerFunc
0.69s0.35%0.35%119.05s59.76%/valyala/fasthttp.(*Server).serveConn
0.04s0.02%0.37%104.22s52.31%internal/poll.ignoringEINTRIO(inline)
101.58s50.99%51.35%103.95s52.18%syscall.Syscall
0.10s0.05%51.40%79.95s40.13%runtime.mcall
0.06s0.03%51.43%79.85s40.08%runtime.park_m
0.23s0.12%51.55%79.30s39.80%runtime.schedule
5.67s2.85%54.39%77.47s38.88%runtime.findrunnable
0.14s0.07%54.46%68.96s34.61%bufio.(*Writer).Flush
16000長連接:
(pprof)top-cum
Showingnodesaccountingfor239.60s,87.07%of275.17stotal
Dropped190nodes(cum=1.38s)
Showingtop10nodesoutof46
flatflat%sum%cumcum%
0.04s0.015%0.015%153.38s55.74%runtime.mcall
0.01s0.0036%0.018%153.34s55.73%runtime.park_m
0.12s0.044%0.062%153s55.60%runtime.schedule
0.66s0.24%0.3%152.66s55.48%runtime.findrunnable
0.15s0.055%0.36%127.53s46.35%poll
127.04s46.17%46.52%127.04s46.17%runtime.epollwait
00%46.52%121s43.97%/valyala/fasthttp.(*workerPool).getCh.func1
00%46.52%121s43.97%/valyala/fasthttp.(*workerPool).worker
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 ISO/IEC TR 27599:2025 EN Information technology – Brain-computer interfaces – Use cases
- 天津市五區(qū)縣重點(diǎn)校聯(lián)考2024-2025學(xué)年高二下學(xué)期4月期中考試 化學(xué)試題(原卷版+解析版)
- 路燈安裝工程承包協(xié)議
- 汽車行業(yè)二手車交易質(zhì)保合同
- 車工基礎(chǔ)知識(shí)試題及答案
- 浙江國企招聘2025湖州安吉國豐熱電有限公司招聘57人筆試參考題庫附帶答案詳解
- 2025重慶廣播電視集團(tuán)(總臺(tái))招聘11人筆試參考題庫附帶答案詳解
- 2025福建福清市匯融創(chuàng)業(yè)投資集團(tuán)有限公司(第一次)招聘8人筆試參考題庫附帶答案詳解
- 2025湖南雙新食品招28人筆試參考題庫附帶答案詳解
- 2025年福建省晉江新絲路康養(yǎng)產(chǎn)業(yè)有限公司招聘6人筆試參考題庫附帶答案詳解
- 統(tǒng)編版2023-2024學(xué)年語文三年級(jí)下冊(cè)第五單元導(dǎo)讀課教學(xué)設(shè)計(jì)
- 三維圓柱擾流-卡門渦街?jǐn)?shù)值仿真方法-詳細(xì)教程
- 2024年陜西延長石油(集團(tuán))有限責(zé)任公司校園招聘考試試題參考答案
- 地籍測量成果報(bào)告
- 2024年蘇州資產(chǎn)管理有限公司招聘筆試沖刺題(帶答案解析)
- 客車防雨密封性要求及試驗(yàn)方法
- 2024春期國開電大??啤端枷氲赖屡c法治》在線形考(專題檢測一至七)試題及答案
- 市場消防安全制度
- 2023-2024學(xué)年蘇州市振華中學(xué)中考沖刺卷數(shù)學(xué)試題含解析
- 牛津3000核心詞匯表注釋加音標(biāo)1-4 完整版
- 農(nóng)貿(mào)市場經(jīng)營管理方案
評(píng)論
0/150
提交評(píng)論