碼農(nóng)架構(gòu) | 怎樣解決超大附件分片上傳?

導(dǎo)讀:分片上傳节槐、斷點(diǎn)續(xù)傳搀庶,這兩個(gè)名詞對于做過或者熟悉文件上傳的朋友來說應(yīng)該不會(huì)陌生拐纱,總結(jié)本篇文章希望對從事相關(guān)工作的同學(xué)能夠有所幫助或者啟發(fā)。

當(dāng)我們的文件特別大的時(shí)候哥倔,上傳是不是需要很長的時(shí)間啊秸架,這么長時(shí)間的長連接,如果網(wǎng)絡(luò)波動(dòng)了呢咆蒿?中間網(wǎng)絡(luò)斷開了呢东抹?在這么長時(shí)間的過程中如果出現(xiàn)不穩(wěn)定的情況,本次上傳的所有內(nèi)容就全部失敗了沃测,又要重新上傳缭黔。

分片上傳,就是將所要上傳的文件蒂破,按照一定的大小馏谨,將整個(gè)文件分隔成多個(gè)數(shù)據(jù)塊(我們稱之為 Part)來進(jìn)行分別上傳,上傳完之后再由服務(wù)端對所有上傳的文件進(jìn)行匯總整合成原始的文件附迷。分片上傳不僅可以避免因網(wǎng)絡(luò)環(huán)境不好導(dǎo)致的一直需要從文件起始位置還是上傳的問題惧互,還能使用多線程對不同分塊數(shù)據(jù)進(jìn)行并發(fā)發(fā)送,提高發(fā)送效率喇伯,降低發(fā)送時(shí)間喊儡。

一、背景


在系統(tǒng)用戶量突增以后稻据,為了更好適配各群體的定制化需求艾猜。業(yè)務(wù)上慢慢實(shí)現(xiàn)了支持 C 端用戶自定義布局和配置,導(dǎo)致配置數(shù)據(jù)讀取 IO 激增攀甚。

為了更好優(yōu)化此類場景箩朴,將用戶自定義配置靜態(tài)化管理!也就是將對應(yīng)的配置文件生成靜態(tài)文件秋度,在生成靜態(tài)文件的過程中遇到棘手的問題炸庞,配置文件文件過大導(dǎo)致在文件上傳服務(wù)器等待時(shí)間過長,致使整個(gè)業(yè)務(wù)場景性能整體下滑荚斯。

image

二埠居、生成配置文件


生成文件三大要素

  • 文件名

  • 文件內(nèi)容

  • 文件存儲(chǔ)格式

文件內(nèi)容、文件存儲(chǔ)格式都好理解和處理事期,當(dāng)然先前整理過微服務(wù)中常用的加密方式

這里做下補(bǔ)充說明滥壕,如果要想對文件內(nèi)容進(jìn)行加密可以考慮。但是本文的案例場景對于配置信息保密程度較低兽泣,這里不做拓展绎橘。

而對于文件名的命名規(guī)范具體結(jié)合業(yè)務(wù)場景來定,通常都是以文件概要+時(shí)間戳格式為主。但是這類命名規(guī)范容易導(dǎo)致文件名沖突称鳞,造成沒有必要的后續(xù)麻煩涮较。

所以我這里對于文件名的命名做了特殊處理,有處理過前端 Route 路由經(jīng)驗(yàn)的應(yīng)該能聯(lián)想到冈止,文件名可以通過基于內(nèi)容生成 Hash 值來代替狂票。

Spring 3.0 之后提供了計(jì)算摘要的的方法。

DigestUtils#md

復(fù)制代碼

返回給定字節(jié)的 MD5 摘要的十六進(jìn)制字符串表示形式熙暴。

image

md5DigestAsHex 源碼

/**

復(fù)制代碼

文件名闺属、內(nèi)容、后綴(存儲(chǔ)格式)確定后直接生成文件

/**

復(fù)制代碼

通過內(nèi)容生成文件優(yōu)點(diǎn)不言而喻周霉,可以極大減少我們主動(dòng)基于內(nèi)容比較來生成新的文件掂器、如果文件內(nèi)容較大生成對應(yīng)的文件名相同則表示內(nèi)容未做任何調(diào)整,此時(shí)我們也就不用做后續(xù)的文件更新操作俱箱。

三唉匾、分片上傳附件


所謂的分片上傳,就是將所要上傳的文件匠楚,按照一定的大小,將整個(gè)文件分隔成多個(gè)數(shù)據(jù)塊(我們稱之為 Part)來進(jìn)行分別上傳厂财,上傳完之后再由服務(wù)端對所有上傳的文件進(jìn)行匯總整合成原始的文件芋簿。分片上傳不僅可以避免因網(wǎng)絡(luò)環(huán)境不好導(dǎo)致的一直需要從文件起始位置還是上傳的問題,還能使用多線程對不同分塊數(shù)據(jù)進(jìn)行并發(fā)發(fā)送璃饱,提高發(fā)送效率与斤,降低發(fā)送時(shí)間。

image

分片上傳主要適用于以下幾種場景:

  • 網(wǎng)絡(luò)環(huán)境不好:當(dāng)出現(xiàn)上傳失敗的時(shí)候荚恶,可以對失敗的 Part 進(jìn)行獨(dú)立的重試撩穿,而不需要重新上傳其他的 Part。

  • 斷點(diǎn)續(xù)傳:中途暫停之后谒撼,可以從上次上傳完成的 Part 的位置繼續(xù)上傳食寡。

  • 加速上傳:要上傳到 OSS 的本地文件很大的時(shí)候,可以并行上傳多個(gè) Part 以加快上傳廓潜。

  • 流式上傳:可以在需要上傳的文件大小還不確定的情況下開始上傳抵皱。這種場景在視頻監(jiān)控等行業(yè)應(yīng)用中比較常見。

  • 文件較大:一般文件比較大時(shí)辩蛋,默認(rèn)情況下一般都會(huì)采用分片上傳呻畸。

image

分片上傳的整個(gè)流程大致如下:

  • 將需要上傳的文件按照一定的分割規(guī)則,分割成相同大小的數(shù)據(jù)塊悼院;

  • 初始化一個(gè)分片上傳任務(wù)伤为,返回本次分片上傳唯一標(biāo)識(shí);

  • 按照一定的策略(串行或并行)發(fā)送各個(gè)分片數(shù)據(jù)塊据途;

  • 發(fā)送完成后绞愚,服務(wù)端根據(jù)判斷數(shù)據(jù)上傳是否完整叙甸,如果完整,則進(jìn)行數(shù)據(jù)塊合成得到原始文件

? 定義分片規(guī)則大小

默認(rèn)情況都以文件達(dá)到 20MB 進(jìn)行強(qiáng)制分片

/**

復(fù)制代碼

為了方便調(diào)試爽醋,強(qiáng)制分片文件的閾值調(diào)整為 1KB

? 定義分片上傳對象

如上圖紅色序號(hào)的文件碎片蚁署,定義分片上傳對象基礎(chǔ)屬性包含附件文件名、原始文件大小蚂四、原始文件 MD5 值光戈、分片總數(shù)、每個(gè)分片大小遂赠、當(dāng)前分片大小逾苫、當(dāng)前分片序號(hào)等

定義基礎(chǔ)屬于便于后續(xù)對文件合理分割愕把、分片的合并等業(yè)務(wù)拓展,當(dāng)然根據(jù)業(yè)務(wù)場景可以定義拓展屬性。

分片總數(shù)

long totalSlices = fileSize % forceSliceSize == 0 ? 

復(fù)制代碼

image

每個(gè)分片大小

long eachSize = fileSize % totalSlices == 0 ? 

復(fù)制代碼

image

原始文件的 MD5 值

MD5Util.hex(file)

復(fù)制代碼

如:

當(dāng)前附件大小為:3382KB朱庆,強(qiáng)制分片大小限制為 1024KB

通過上述計(jì)算:分片數(shù)量為 4 個(gè)每個(gè)分片大小為 846KB

image

? 讀取每個(gè)分片的數(shù)據(jù)字節(jié)

標(biāo)記當(dāng)前字節(jié)下標(biāo)吹散,循環(huán)讀取 4 個(gè)分片的數(shù)據(jù)字節(jié)

try (InputStream inputStream = new FileInputStream(uploadVO.getFile())) {

復(fù)制代碼

image

三滚澜、總結(jié)


所謂的分片上傳,就是將所要上傳的文件蜕乡,按照一定的大小奸绷,將整個(gè)文件分隔成多個(gè)數(shù)據(jù)塊(我們稱之為 Part)來進(jìn)行分別上傳。

處理大文件進(jìn)行分片主要核心確定三大點(diǎn)

  • 文件分片粒度大小

  • 分片如何讀取

  • 分片如何存儲(chǔ)

本篇文章主要分析和處理大文件上傳過程中如何針對大文件文件文件內(nèi)容比較层玲、進(jìn)行分片處理号醉。合理設(shè)置分片閾值以及如何讀取和標(biāo)記分片。希望對從事相關(guān)工作的同學(xué)能夠有所幫助或者啟發(fā)辛块。后續(xù)會(huì)對分片如何存儲(chǔ)畔派、標(biāo)記、合并文件進(jìn)行詳細(xì)解讀润绵。

原文:微服務(wù)架構(gòu) | 怎樣解決超大附件分片上傳线椰?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市尘盼,隨后出現(xiàn)的幾起案子士嚎,更是在濱河造成了極大的恐慌,老刑警劉巖悔叽,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莱衩,死亡現(xiàn)場離奇詭異,居然都是意外死亡娇澎,警方通過查閱死者的電腦和手機(jī)笨蚁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人括细,你說我怎么就攤上這事伪很。” “怎么了奋单?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵锉试,是天一觀的道長。 經(jīng)常有香客問我览濒,道長呆盖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任贷笛,我火速辦了婚禮应又,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘乏苦。我一直安慰自己株扛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布汇荐。 她就那樣靜靜地躺著洞就,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掀淘。 梳的紋絲不亂的頭發(fā)上奖磁,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天,我揣著相機(jī)與錄音繁疤,去河邊找鬼。 笑死秕狰,一個(gè)胖子當(dāng)著我的面吹牛稠腊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸣哀,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼架忌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了我衬?” 一聲冷哼從身側(cè)響起叹放,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挠羔,沒想到半個(gè)月后井仰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡破加,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年俱恶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,664評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡合是,死狀恐怖了罪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情聪全,我是刑警寧澤泊藕,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站难礼,受9級特大地震影響娃圆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹤竭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一踊餐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧臀稚,春花似錦吝岭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至稚机,卻和暖如春幕帆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赖条。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工失乾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纬乍。 一個(gè)月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓碱茁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仿贬。 傳聞我的和親對象是個(gè)殘疾皇子纽竣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內(nèi)容