《面試篇》Http協(xié)議 中,我們有提到大文件下載和斷點(diǎn)續(xù)傳,本篇我們就來(lái)開(kāi)發(fā)一個(gè)多線程文件下載器,最后我們用這個(gè)多線程下載器來(lái)突破下載的限速。
兄弟們看到這個(gè)標(biāo)題可能會(huì)覺(jué)得是個(gè)標(biāo)題黨,為了解決疑慮,我們先來(lái)看下最終的測(cè)試結(jié)果:
測(cè)試云盤(pán)下載的文件 46M,自己本地最大下載速度 2M
測(cè)試結(jié)果,「提速46倍」,我還是太謙虛了,只說(shuō)提速30倍,此處我們覺(jué)得應(yīng)該有掌聲(我聽(tīng)不到,還是點(diǎn)贊實(shí)在)
?源碼地址:https://gitee.com/silently9527/fast-download
喜歡請(qǐng)記得star哦
?
Range主要是針對(duì)只需要獲取部分資源的范圍請(qǐng)求,通過(guò)指定Range即可告知服務(wù)器資源的指定范圍。格式: Range: bytes=start-end
比如:獲取字節(jié)范圍 5001-10000
Range: bytes=5001-10000
也可以指定開(kāi)始位置不指定結(jié)束位置,表示獲取開(kāi)始位置之后的全部數(shù)據(jù)
Range: bytes=5001-
服務(wù)器接收到帶有Range的請(qǐng)求,會(huì)在處理請(qǐng)求之后返回狀態(tài)碼為206 Partial Content的響應(yīng)。
基于Range的特性,我們就可以實(shí)現(xiàn)文件的多線程下載,文件的斷點(diǎn)續(xù)傳
本文我們使用的SpringMVC中的RestTemplate;由于云盤(pán)的鏈接是Https,所以我們需要設(shè)置RestTemplate繞過(guò)證書(shū)驗(yàn)證
pom.xml
RestTemplateBuilder
DisplayDownloadSpeed
因?yàn)橛?jì)算下載速度,我們需要知道每秒傳輸?shù)淖止?jié)數(shù)是多少,為了監(jiān)控傳輸數(shù)據(jù)的過(guò)程,我們需要了解SpringMVC中的接口ResponseExtractor
ResponseExtractor
該接口只有一個(gè)方法,當(dāng)客戶端和服務(wù)器端連接建立之后,會(huì)調(diào)用這個(gè)方法,我們可以在這個(gè)方法中監(jiān)控下載的速度。
AbstractDisplayDownloadSpeedResponseExtractor
這里使用的是restTemplate調(diào)用execute, 先文件獲取到字節(jié)數(shù)組, 再將字節(jié)數(shù)組直接寫(xiě)到目標(biāo)文件。
這里我們需要注意的點(diǎn)是: 這種方式會(huì)將文件的字節(jié)數(shù)組全部放入內(nèi)存中, 及其消耗資源;我們來(lái)看看如何實(shí)現(xiàn)。
ByteArrayResponseExtractor
執(zhí)行一段時(shí)間之后,我們可以看到內(nèi)存已經(jīng)使用了800M左右,所以這種方式只能使用于小文件的下載,如果我們下載幾G的大文件,內(nèi)存肯定是不夠用的。至于下載時(shí)間,因?yàn)槲募笠矝](méi)有等下載完成就結(jié)束了程序。
上面的方式只能下載小的文件,那大文件的下載我們?cè)撚檬裁捶绞侥??我們可以把流輸出到文件而不是?nèi)存中。接下來(lái)我們來(lái)實(shí)現(xiàn)我們大文件的下載。
執(zhí)行一段時(shí)間之后,我們?cè)倏纯聪聝?nèi)存的使用情況,發(fā)現(xiàn)這種方式內(nèi)存消耗較少,效果比較理想,下載時(shí)間:199s
如果服務(wù)器不限速的話,通常能夠把自己本地的帶寬給跑滿,那么使用單線程下載就夠了,但是如果遇到服務(wù)器限速,下載速度遠(yuǎn)小于自己本地的帶寬,那么可以考慮使用多線程下載。多線程我們使用CompletableFuture(可以參考之前的文章 《CompletableFuture讓你的代碼免受阻塞之苦》)。
實(shí)現(xiàn)多線程文件下載的基本流程:
完成代碼如下:
從執(zhí)行的結(jié)果上來(lái)看,因?yàn)殚_(kāi)啟了30個(gè)線程同時(shí)在下載,內(nèi)存的占用要比單線程消耗的多,但是也在接受范圍內(nèi),下載時(shí)間:81s,速度提升2.5倍,這是因?yàn)閕dea的下載服務(wù)器沒(méi)有限速,本次多線程速度的提升僅僅是在充分的壓榨本地的帶寬,所以提示的幅度不大。
因?yàn)樵票P(pán)對(duì)單個(gè)線程的下載速度做了限制,大概是在100kb,所以我們使用云盤(pán)的下載鏈接,來(lái)測(cè)試多線程和單線程的下載速度。
測(cè)試云盤(pán)中 46M 的文件的下載速度,自己本地最大下載速度 2M
獲取文件的下載地址
?注意:從瀏覽器中獲取的鏈接需要先使用URLDecode解碼,否則下載會(huì)失敗,并且云盤(pán)文件的下載鏈接是有時(shí)效性的,過(guò)期后就不能在下載,需要重新生成下載鏈接
?
執(zhí)行的結(jié)果可以看出,云盤(pán)對(duì)單線程的下載限速真的是喪心病狂, 46M的文件下載需要耗時(shí):600s
為了充分的壓榨網(wǎng)速,找出最合適的線程數(shù),所以測(cè)試了不同線程數(shù)的下載速度
線程數(shù) 下載總耗時(shí) 10 60s 20 30s 30 21s 40 15s 50 13s
從測(cè)試的結(jié)果上來(lái)看,對(duì)于自己的運(yùn)行環(huán)境把線程數(shù)設(shè)置在30個(gè)左右比較合適
咨詢熱線:
86-592-5151555
地址: 廈門(mén)市集美區(qū)軟件園三期A3棟504室
QQ:1039899831
固話:86-592-5151555
手機(jī):18020730588(賴先生)
官網(wǎng):www.tiptop.cn
Copyright © 2000-2021 www.tiptop.cn
游戲作品版權(quán)歸原作者享有,如無(wú)意之中侵犯了您的版權(quán),請(qǐng)您按照《版權(quán)保護(hù)投訴指引》來(lái)信告知,本網(wǎng)站將應(yīng)您的要求刪除。