老弟做了个网盘,炸了!
趣講文件上傳功能的巧妙設計
大家好,我是魚皮。
不知道大家有沒有想過制作一款自己的網盤呢?這不,我學編程的老弟小阿巴做了一個,非常激動地找我來體驗。
打開網盤,界面仿的還不錯,我簡單試了下文件的上傳和下載,沒有什么問題。
正當小阿巴洋洋得意時,我試著上傳一個 1 GB 大小的文件。結果文件上傳到 99% 時,網絡一抖,文件上傳失敗,竟然還要從 0 開始重新上傳?!
小阿巴無奈地撓撓頭:網絡不好,怪我咯?
我直接一巴掌甩過去,要知道,制作網盤可不是一件容易的事!
先從最基礎的功能來說,要實現文件的上傳、存儲、下載、文件和目錄管理。如果要真正上線、開放給其他人使用,還要考慮到權限管理、接口訪問、CDN 加速,無論哪點自己來做都是很麻煩的。
所以除了學習之外,如果想要搭建自己的私人網盤,建議直接選擇一些開源的,比如主流的 Seafile、Nextcloud、Cloudreve、OwnCloud 都可以。
當然,公用網盤最要命的還是帶寬、存儲等資源的費用,所以為了節約成本、支持更多用戶訪問,很多網盤都采取了限速、限制容量策略。
小阿巴:做了網盤這么麻煩啊,我放棄我放棄。。。
我笑到:雖然想做好網盤很難,但我們可以一步步來,學習每個功能中的優秀設計,相信最后也能做出一款不錯的網盤。今天就先從 文件上傳 講起吧,解決下剛剛上傳失敗必須從 0 重新上傳的問題等。
文件上傳設計
文件上傳顧名思義就是把文件從本地電腦發送到存儲文件的遠程服務器上,小文件的上傳倒沒有什么好說的,主要考慮的是大文件上傳怎么 更快、更穩定、更靈活、更快響應 等等,以提高用戶的體驗。
這里分享幾個經典的大文件上傳設計,包括文件分塊、并發上傳、斷點續傳、秒傳、異步上傳。
文件分塊
既然小文件的處理相對容易,那不妨在發送前,把大文件分割為多個連續的小文件,一塊一塊地發送。
此外,需要在發送每一個文件塊時,額外傳輸一些信息,比如當前塊數、文件總塊數、文件大小、所屬原文件標識(MD5)等:
這樣,服務器就能一塊一塊地接收,把這些文件塊保存到臨時目錄中。當接收到最后一塊時,把之前的所有文件塊再拼接到一起,就能組成完成的原文件啦。
并發上傳
將大文件分塊后,就可以通過多線程并發上傳,同時傳輸多個塊:
要根據網絡情況決定是否并發上傳、同時并發上傳多少個塊,不是并發數越多越好。網絡好的話,并發數量調大一些,能夠大大提高文件整體上傳效率;相反,盲目調整并發數,上傳可能會更慢。
斷點續傳
對于大文件來說,上傳中斷后如果要從 0 開始重傳,就太讓人崩潰了!
推薦使用斷點續傳技術,原理很簡單,在文件分塊的基礎上,服務器記錄一下原文件對應的上傳進度,每接收到一個塊,就更新一下進度。這樣,即使網絡故障導致上傳失敗,也能從上傳進度中知道哪些文件塊已上傳、接下來需要從哪一塊重新開始了,而不用從第 1 塊開始重新傳輸。
該原理同樣適用于文件下載。
斷點續傳有很多種實現方式,自主實現、HTTP 協議 1.1 等,感興趣的同學可以了解下。
秒傳
不知道大家有沒有發現,有時,我們上傳一個幾 GB 的超大文件竟然可以在 1 秒內完成!
這是咋實現的呢?真相只有一個,該文件肯定之前已經被上傳過了!
這就是經典的秒傳技術。
上傳文件前,先在客戶端(比如瀏覽器)根據文件內容計算出文件的 MD5 值,相同內容的文件 MD5 值必然相同。然后在服務器已上傳文件數據庫中查找該 MD5 對應的文件是否已存在。如果不存在,上傳文件并在上傳成功后將該文件信息插入數據庫,過程如下:
若文件已存在,直接新建一個對該文件的引用就行了,不必重復上傳,過程如下:
不過要注意,不同內容文件的 MD5 值也可能會相同(碰撞),導致用戶下載到不是自己上傳的文件,所以檢驗重復時,還可以補充一些校驗,比如針對文件前幾位再生成一個 MD5、用其他 Hash 算法再生成一個校驗值等。
異步上傳
除了同步上傳外,當我們要上傳的文件不在本地而是已經存在對應 url 時,也可以采用 全異步上傳 的方式,將文件上傳變成一個 任務 。
用戶輸入要上傳的文件 url,點擊上傳后,不需要一直在文件上傳頁面等著,而是只需要告訴后臺 “我要執行文件上傳”,并向后臺新建一個文件上傳任務,就可以快速響應用戶了,比如 “文件上傳中,請留意通知”。等后臺取出并真正完成文件上傳的任務后,給用戶發送通知就可以了。
整體步驟如下:
最后,如果只是需要在開發中用到文件上傳,大可不必自己實現上述功能,用個現成的對象存儲服務就好了。比如七牛云,分塊上傳什么的都給我們做好了,也可以參考七牛云 SDK 文檔(https://github.com/qiniu)來了解它們的實現方式。
我是魚皮,最后再送大家一些 幫助我拿到大廠 offer 的學習資料:
跑了,留下 6T 的資源!
歡迎閱讀 我從 0 自學進入騰訊的編程學習、實習、求職、考證、寫書經歷,不再迷茫!
我學計算機的四年,共勉!
以上就是本期分享,有幫助的話點個贊吧 ??
總結
以上是生活随笔為你收集整理的老弟做了个网盘,炸了!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 15 道超经典大厂 Java 面试题!重
- 下一篇: linux的IP配置