Web Secret:圖片服務(wù)
(一)構(gòu)建一個基本的圖片服務(wù)
選擇這個主題是因?yàn)樘^簡單,簡單到你甚至?xí)谠O(shè)計(jì)中忽略這個主題,哪個網(wǎng)站不需要圖片呢,又有哪個網(wǎng)站完全不支持用戶上傳圖片,可是我們又有多少人真正考慮過圖片上傳的事情呢?我們就以一個典型的SNS或者論壇來說,至少會有這么幾個情況你需要使用到圖片:
n 應(yīng)用程序需要使用到的背景圖、圖標(biāo)和一些界面修飾
n 用戶個人的頭像,一般來說會有縮略圖和頭像圖
n 用戶個人相冊,允許用戶上傳一定的個人照片
n 文章/博客中的圖片
n ……
假設(shè)我們的網(wǎng)站叫著www.websecretapp.com ,現(xiàn)在我們來看最簡單的處理方法:
1. 在網(wǎng)站的根目錄下建立一個名為Upload的目錄,也就是http://websecretapp.com/upload。
2. http://www.websecret.com/photoupload 提供圖片上傳的處理,您可以選擇自己熟悉的任何語言,當(dāng)然了,photoupload.php,photoupload.jsp,photoupload.aspx等等都可以。
3. 提供一個upload.html的頁面,讓用戶可以選擇本地文件上傳到您指定的圖片上傳地址。
4. 在photoupload中獲取文件的字節(jié)流,用你自己的算法生成一個服務(wù)器端的文件名,如abcdef.jpg。
5. 將得到的字節(jié)流存儲到Upload的本地目錄,文件名為abcdef.jpg。
6. 返回 http://www.websecretapp.com/upload/abcdef.jpg,并把這個地址存儲在您的數(shù)據(jù)庫或者文章內(nèi)容里。
7. 提示用戶上傳成功。
這樣的工作相信我們在五分鐘內(nèi)可以做完,也就意味著一個基礎(chǔ)的圖片上傳服務(wù)已經(jīng)提供了,這個時候我們來考慮還有哪些問題,應(yīng)該做一些怎樣的調(diào)整讓圖片服務(wù)看起來還那么回事:
l 應(yīng)用和圖片的存儲是放在一個目錄下的
如此一來,時間長了會導(dǎo)致整個網(wǎng)站的內(nèi)容變得巨大無比,應(yīng)該考慮將圖片和應(yīng)用分開以方面日后的管理,這個時候我們可以做這樣的調(diào)整:
a) 將圖片存儲到其他的目錄,然后使用建立一個叫著Upload的虛擬目錄,圖片地址還是可以用 http://www.websecretapp.com/upload/abcdef.jpg 來訪問。
b) 有多個域名的話,我可以建立一個叫著http://img.websecretapp.com 的站點(diǎn),然后把根目錄配制成圖片存儲的目錄,這樣一來,上傳圖片的地址就變成 http://img.websecret.com/abcdef.jpg 。
l 不同業(yè)務(wù)的圖片混合在一起
為了解決這個問題,我們可以建立user和article的目錄,在上傳的時候選擇存儲到相對應(yīng)的目錄,這個時候分別對應(yīng)的圖片地址是:
http://img.websecretapp.com/user/adcdef.jpg
http://img.websecretapp.com/article/abcdef.jpg
不同業(yè)務(wù)的圖片存儲在不同的目錄,對于業(yè)務(wù)來說,已經(jīng)更進(jìn)了一步。
l 對于圖片的大小和類型沒有做任何限制
我們可以在服務(wù)器代碼判斷上傳的文件類型,如果不是“jpg,gif,png”,則提示用戶不正確的文件類型。
圖片的大小不允許超過2M,除非你的應(yīng)用需要,大多而言,你并不需要提供原始圖片的顯示,一個是太過占據(jù)帶寬,一個是過于浪費(fèi)您的存儲空間,當(dāng)然了,如果您的客戶端代碼沒有特別處理,對于帶寬比較低的用戶來說,上傳過程甚至出出現(xiàn)“假死”現(xiàn)象。我們可以做這樣的工作:
1. 在客戶端判斷上傳文件的類型,如果不是可以接受的類型,則在界面上提示用戶。
2. 對于太大的文件,通過獲取文件的字節(jié)流大小來判斷,如果超過限制,提示用戶超過允許的限制。
3. 大多情況下來說,用戶選擇上傳數(shù)碼相機(jī)里的照片,基本上都會是2048x1536,質(zhì)量好一點(diǎn)的話,應(yīng)該會在2M左右。而在Web上瀏覽的照片,1024 x768基本上可以滿足要求,這個時候可以選擇服務(wù)器壓縮,而在不影響視覺質(zhì)量的情況下,通常是可以壓縮成150K以下的;谶@個考慮,服務(wù)器存儲的大圖片需要事先壓縮。
l 所有的圖片存儲在同一個目錄下
同一個目錄下如果文件數(shù)過多的話,會導(dǎo)致嚴(yán)重的性能問題,不同的文件系統(tǒng)也存在性能的差異,但是不管如何,將所有的文件放在同一層目錄下并不是最好的做法,這個時候我們需要分目錄,至于如何劃分目錄,則會有不同做法,比較常見的是下面兩種:
1. 取文件名的MD5加密字符串,然后根據(jù)字母來分目錄,比如可以分區(qū)成http://img.websecretapp.com/user/ae/3f/abcdef.jpg ,ae/3f就是根據(jù)md5字符串來區(qū)分的,基于文件名哈希也可以。
2. 根據(jù)日期來劃分,可以將文件夾分區(qū)成 http://img.websecretapp.com/user/2008/04/05/abcdef.jpg ,許多網(wǎng)站會采用這樣的方式來散列圖片的分布,優(yōu)點(diǎn)很簡單,所有的都是以業(yè)務(wù)時間點(diǎn)來增長的,從管理的角度來說,也方便增量備份。當(dāng)然了,也會提出反對的,那就是目錄樹過深,特別是當(dāng)天的數(shù)據(jù)量不是很大,每天一個文件夾也就不是完全必要。
不管用怎樣的方式散列文件分布,具體的還是根據(jù)業(yè)務(wù)的具體情況而定,選擇合適自己的就可以。
而下面的圖則是描述了整個圖片上傳的基本流程

到目前為止我們已經(jīng)完成了對一個簡單圖片服務(wù)的討論,在第一個版本的基礎(chǔ)上,我們需要作下面的考慮:
ü 將圖片服務(wù)器和應(yīng)用服務(wù)器分開
ü 不同的業(yè)務(wù)圖片分別存儲,盡量不要混合
ü 審查業(yè)務(wù)的需要,盡量在存儲之前壓縮圖片,而不是存儲原圖
ü 采用適合自己的策略對文件進(jìn)行散列存儲,以避免單一目錄下文件數(shù)過多的情況
在后續(xù)的篇幅中,我們將繼續(xù)討論如何擴(kuò)展這個服務(wù)以及需要考慮的問題。 |