打包下載服務(wù)

有組織就有協(xié)作劫瞳,有協(xié)作就有共享呕童,想把共享作為資源保留就要屯盤(pán)建庫(kù)崔赌。你產(chǎn)品的用戶(hù)接下來(lái)會(huì)問(wèn):“我能否把選好的資源打包下載呢意蛀?”,衣食父母的吩咐這得接著峰鄙。如何設(shè)計(jì)一個(gè)靠譜的打包下載服務(wù)呢?

摘要如下

要求
- 即刻下載
- 瀏覽器支持
- 獨(dú)立可復(fù)用
- 并發(fā)訪問(wèn)
- 資源占用小
- 安全
- 高可用太雨、高并發(fā)

設(shè)計(jì)
- 性能考慮:放棄壓縮
- 資源考慮:按流處理
- 并發(fā)考慮:Golang實(shí)現(xiàn)web服務(wù)
- 安全考慮:secure-token auth
- 獨(dú)立可復(fù)用考慮:獨(dú)立無(wú)狀態(tài)服務(wù)
- 瀏覽器支持考慮:小心處理
- 高可用吟榴、高并發(fā)考慮:集群方案

實(shí)現(xiàn)

要求

注定是產(chǎn)品經(jīng)理和技術(shù)總監(jiān)都必須滿意的,架構(gòu)師心里暗自打鼓囊扳。

即刻下載

產(chǎn)品經(jīng)理說(shuō)了:點(diǎn)擊打包下載按鈕之后還提示讓用戶(hù)等 “ZIP文件準(zhǔn)備就緒吩翻,請(qǐng)點(diǎn)擊鏈接” 的通知再開(kāi)始下載,這是不能接受的锥咸,說(shuō)好的無(wú)需等待呢狭瞎?

技術(shù)總監(jiān)說(shuō)了:點(diǎn)擊打包下載按鈕之后就 Loading 十幾秒甚至幾十秒直到下載開(kāi)始,這是不能接受的搏予。性能要好熊锭,否則大文件的話到底等到什么時(shí)候去?

瀏覽器支持

產(chǎn)品經(jīng)理說(shuō)了:產(chǎn)品的用戶(hù)群挺廣,用什么瀏覽器的用戶(hù)都有碗殷,都能支持的吧精绎?特別是從IE下載,文件名可不能是亂碼的锌妻。

獨(dú)立可復(fù)用

技術(shù)總監(jiān)說(shuō)了:做一個(gè)服務(wù)代乃,就要能獨(dú)立部署,要能被幾個(gè)產(chǎn)品復(fù)用仿粹。每個(gè)產(chǎn)品都來(lái)一套的話搁吓,可接受不了。

產(chǎn)品經(jīng)理說(shuō)了:每個(gè)產(chǎn)品要下載的資源可能來(lái)自不同地方吭历,要能支持任意源地址堕仔。

并發(fā)訪問(wèn)

產(chǎn)品經(jīng)理說(shuō)了:我們估計(jì)了初期同時(shí)使用打包下載的用戶(hù)數(shù),支持千人并發(fā)訪問(wèn)就可以了毒涧,圖片文檔下載嘛文件都不大贮预,我們會(huì)限制讓用戶(hù)一次不能下載很多文件的。

資源占用小

技術(shù)總監(jiān)說(shuō)了:經(jīng)費(fèi)有限契讲,初期用戶(hù)用得也不頻繁仿吞,這個(gè)服務(wù)只能給你們劃一臺(tái)低配置的VM,2核CPU捡偏、2G內(nèi)存唤冈、20GB硬盤(pán)夠了吧,日志不能丟哦银伟,好好干......

安全

產(chǎn)品經(jīng)理說(shuō)了:網(wǎng)上很多資源都存在被盜鏈或竊取的情況你虹,用戶(hù)A打包下載zip文件之后,這個(gè)zip文件不會(huì)被其他人再下載或盜鏈吧彤避?要保證安全哦傅物。

高可用、高并發(fā)

技術(shù)總監(jiān)說(shuō)了:用戶(hù)會(huì)積少成多琉预,架構(gòu)設(shè)計(jì)要走在前面董饰。高可用性如何保證?更高的并發(fā)訪問(wèn)如何應(yīng)對(duì)圆米?

不斷點(diǎn)頭稱(chēng)是的架構(gòu)師此刻腦子飛快的運(yùn)轉(zhuǎn)著卒暂,一面在心里再次確認(rèn)這些要求不是空想,一面如玩魔方一般拼湊思路進(jìn)行設(shè)計(jì)娄帖。

設(shè)計(jì)

傳統(tǒng)的文件打壓縮包方案

步驟如下也祠,缺點(diǎn)在括號(hào)內(nèi)。這些資源消耗在并發(fā)量增大時(shí)會(huì)急劇上升近速,VM資源成為瓶頸诈嘿。

  1. 從各源地址下載源文件到服務(wù)器(有等待時(shí)間堪旧,源文件臨時(shí)占硬盤(pán))
  2. 打包壓縮(有等待時(shí)間,壓縮很耗CPU)
  3. 提供壓縮包文件可對(duì)外下載(壓縮包占硬盤(pán))

性能考慮:放棄壓縮

在前文列出的《要求》里永淌,并沒(méi)有著重提到打包的壓縮比崎场,其原因

  • 用戶(hù)最需要的是打包,即免去一個(gè)一個(gè)下載文件的繁瑣遂蛀。
  • 用戶(hù)關(guān)心的是能否立刻開(kāi)始下載谭跨,而不苛求下載的文件大小與時(shí)間。
  • 用戶(hù)打包的文件中李滴,除了文檔之外螃宙,如照片、視頻所坯、PDF文件可壓縮尺寸的余地太小谆扎,壓縮反倒徒勞。

放棄壓縮之后芹助,拿到源文件的第一塊內(nèi)容之后就立刻可以生成打包文件了堂湖,省下CPU資源,省下等待時(shí)間状土。假設(shè)要求輸出是ZIP包无蜂,無(wú)壓縮的包仍是ZIP格式。

對(duì)糾結(jié)用戶(hù)下載流量大小的人蒙谓,告訴你打包下載的內(nèi)容是經(jīng)過(guò) gzip 再由瀏覽器解開(kāi)的斥季,你可以安心了。

資源考慮:按流處理

既然放棄壓縮累驮,省下的工作都是I/O酣倾,即搬運(yùn)源文件內(nèi)容到服務(wù)器,再以一個(gè)文件的形式搬運(yùn)到用戶(hù)手里谤专,為什么中間要存一次文件呢躁锡?我們大可以把前后兩個(gè)管道接上,拿到的每一塊源文件內(nèi)容都立即倒手給用戶(hù)置侍。

我們只要明白并處理好

  • 無(wú)壓縮的打包只是把源文件內(nèi)容一個(gè)一個(gè)接起來(lái)映之,形成一個(gè)文件而已。
  • 文件下載起始需要一個(gè)預(yù)估大小墅垮,只能多惕医,不能少耕漱。

按流處理之后算色,無(wú)論源文件或打包產(chǎn)出文件都無(wú)需存在硬盤(pán)上了,剩下硬盤(pán)資源螟够,剩下I/O時(shí)間灾梦。

并發(fā)考慮:Golang實(shí)現(xiàn)web服務(wù)

打包下載服務(wù)仍是請(qǐng)求響應(yīng)模型的web服務(wù)峡钓。如何提高并發(fā)下載數(shù)?在資源緊張的情況下

  • 多進(jìn)程較為消耗資源若河,考慮使用多線程或協(xié)程
  • I/O 為主能岩,考慮使用貼近底層的語(yǔ)言
  • web 服務(wù)選簡(jiǎn)單些的框架,不需要 view萧福、不需要 session拉鹃、不需要關(guān)系數(shù)據(jù)模型

結(jié)果 Golang 語(yǔ)言勝出,采用 Golang 內(nèi)置的 http 庫(kù)由 goroutine 支持并發(fā)鲫忍。

安全考慮:secure-token auth

打包下載服務(wù)授予 key pair 給服務(wù)使用者膏燕,并約定共同的hash算法,由服務(wù)使用者發(fā)出請(qǐng)求前做簽名生成 token悟民,之后由打包下載服務(wù)驗(yàn)證簽名坝辫,并進(jìn)一步驗(yàn)證是否過(guò)期以反盜鏈。

在打包下載服務(wù)這里實(shí)際只做了驗(yàn)證(authentication)射亏,而沒(méi)有做授權(quán)(authorization)近忙。沒(méi)錯(cuò),任何簽名正確且未過(guò)期的請(qǐng)求都可以被放行智润。你應(yīng)該注意到了及舍,簽名請(qǐng)求的是服務(wù)使用者,那是你的某個(gè)使用此服務(wù)的產(chǎn)品做鹰,不是最終用戶(hù)击纬,對(duì)最終用戶(hù)做授權(quán)是各產(chǎn)品自己的事,這也是為獨(dú)立性的考慮钾麸。

獨(dú)立可復(fù)用考慮:獨(dú)立無(wú)狀態(tài)服務(wù)

服務(wù)中必須把獨(dú)立做到極致更振,才易復(fù)用

  • 不耦合任何產(chǎn)品里的業(yè)務(wù)和代碼
  • 不存儲(chǔ)任何產(chǎn)品的數(shù)據(jù)
  • 容器化,把代碼打成docker image饭尝,按需要的配置啟動(dòng)container
  • 只接受可直接訪問(wèn)的源文件地址肯腕,并在打包前發(fā)option請(qǐng)求嘗試訪問(wèn)
  • auth算法是公開(kāi)的,只有key pairs是服務(wù)自己存儲(chǔ)的钥平,前一節(jié)提到過(guò)

瀏覽器支持考慮:小心處理

這是些十分大眾又出名的坑实撒,小心處理就是。

小心文件名
  • IE和現(xiàn)代瀏覽器對(duì)UTF8文件名的對(duì)待是有區(qū)分的涉瘾,我們?cè)诜?wù)端都滿足它們知态。
  • 不同瀏覽器對(duì)特殊字符的轉(zhuǎn)換也是有差異的,我們?cè)诜?wù)里直接統(tǒng)一改好名立叛,同時(shí)做到區(qū)別重名负敏。
別拼接源文件地址進(jìn) URL

提出打包下載請(qǐng)求肯定要帶著若干源文件的地址,發(fā)一個(gè) POST ajax 請(qǐng)求比較理想秘蛇。因?yàn)槿暨x GET 請(qǐng)求只能拼 URL其做,源文件地址的URL長(zhǎng)度和數(shù)目未知顶考,存在超過(guò) URL 長(zhǎng)度限制的可能(IE有2084個(gè)字節(jié)的限制)。
POST 請(qǐng)求帶回一個(gè)固定長(zhǎng)度的存根妖泄,在回調(diào)方法里再組裝一個(gè)下載打包文件的 URL驹沿,直接打開(kāi)它就可以啟動(dòng)下載了。這兩個(gè)請(qǐng)求的銜接是一個(gè)用戶(hù)無(wú)法干預(yù)的連貫動(dòng)作蹈胡,所以時(shí)間很快渊季,所以把存根存放在內(nèi)存數(shù)據(jù)庫(kù)如 Redis 中可以設(shè)一個(gè)很快的過(guò)期時(shí)間。

高可用罚渐、高并發(fā):集群方案

看了前文梭域,你該知道這個(gè)服務(wù)被設(shè)計(jì)成獨(dú)立無(wú)狀態(tài)的。和其他集群一樣搅轿,一個(gè)負(fù)載均衡器就可實(shí)現(xiàn)病涨。

但是前文我說(shuō)過(guò)是用 docker 部署的,我推薦在幾個(gè)VM之間建 docker swarm璧坟,直接利用 docker 的 ingress 網(wǎng)絡(luò)特性來(lái)做負(fù)載均衡既穆,通過(guò)橫向擴(kuò)展 docker swarm 中節(jié)點(diǎn)數(shù)目和container數(shù)目來(lái)支持更高并發(fā)。

存根依賴(lài)的內(nèi)存數(shù)據(jù)庫(kù)如 Redis 自然也需要做集群雀鹃,負(fù)載很小幻工,只為高可用。

實(shí)現(xiàn)

你很走運(yùn)黎茎,我已實(shí)現(xiàn)好了囊颅,拿去吧~

demo: http://zipper.demo.wushaobo.info
github: https://github.com/wushaobo/zipper
docker: https://hub.docker.com/r/wushaobo/zipper

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市傅瞻,隨后出現(xiàn)的幾起案子踢代,更是在濱河造成了極大的恐慌,老刑警劉巖嗅骄,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胳挎,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡溺森,警方通過(guò)查閱死者的電腦和手機(jī)慕爬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)屏积,“玉大人医窿,你說(shuō)我怎么就攤上這事〈读郑” “怎么了姥卢?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)铛铁。 經(jīng)常有香客問(wèn)我隔显,道長(zhǎng),這世上最難降的妖魔是什么饵逐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任括眠,我火速辦了婚禮,結(jié)果婚禮上倍权,老公的妹妹穿的比我還像新娘掷豺。我一直安慰自己,他們只是感情好薄声,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布当船。 她就那樣靜靜地躺著,像睡著了一般默辨。 火紅的嫁衣襯著肌膚如雪德频。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天缩幸,我揣著相機(jī)與錄音壹置,去河邊找鬼。 笑死表谊,一個(gè)胖子當(dāng)著我的面吹牛钞护,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播爆办,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼难咕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了距辆?” 一聲冷哼從身側(cè)響起余佃,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎跨算,沒(méi)想到半個(gè)月后咙冗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漂彤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年雾消,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挫望。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡立润,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出媳板,到底是詐尸還是另有隱情桑腮,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布蛉幸,位于F島的核電站破讨,受9級(jí)特大地震影響丛晦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜提陶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一烫沙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧隙笆,春花似錦锌蓄、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至铅忿,卻和暖如春剪决,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背檀训。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工昼捍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肢扯。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓妒茬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蔚晨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乍钻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,111評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)铭腕,斷路器银择,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • Ubuntu的發(fā)音 Ubuntu被盈,源于非洲祖魯人和科薩人的語(yǔ)言析孽,發(fā)作 oo-boon-too 的音。了解發(fā)音是有意...
    螢火蟲(chóng)de夢(mèng)閱讀 99,260評(píng)論 9 467
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,810評(píng)論 6 342
  • 今天提起健身的意念了只怎,就因?yàn)楝F(xiàn)在我已經(jīng)感覺(jué)我是一個(gè)虎背熊腰的女人了袜瞬,實(shí)在已經(jīng)不能說(shuō)美了,好郁悶身堡,所以一定要健身了邓尤。...
    幽蘭依依閱讀 136評(píng)論 2 1