首先說說分佈式文件系統應對的需求吧;html
有些應用涉及到不少文件的頻繁上傳和下載,若是咱們將上傳的文件保存到服務裏的本地硬盤中,隨着時間的推移,這個系統可能再也容納不下其餘的數據,還有就是文件的共享問題,參與集羣的某個服務啓用了圖片保存在本地,參與集羣的其餘機器卻獲取不到該圖片數據,單點問題無可置疑的夜存在,併發能力不強,還增長該服務器的web或者Nginx的壓力java
分佈式文件系統的好處就是處理上面的諸多窘迫,將文件數據儲存在多個機器上,這些機器經過網絡鏈接,有統一的管理,有備份,有負載均衡等等...nginx
分佈式文件系統按保存數據大小來分,中小容量非FastDFS莫屬了,文件大小建議在500m範圍內,支持圖片,視頻等小型文件的大量儲存,好比相冊網站,或者短小視頻網站,若是企業使用的第三方搭建的服務,實際上是有必定的安全隱患的,你想假如你是一個短視頻娛樂的項目,你把這種文件數據保存第三方的文件保存系統中,萬一第三方公司跑路了,你的公司離崩盤也不遠了,因此通常仍是本身搭建分佈式文件保存系統,安全一些;git
FastDFS的話,是由淘寶"餘慶"先生開發出來的一個純C的分佈式文件系統,致力於解決互聯網三高 [高併發、高性能、高可用];程序員
首先從大的方面看的話,FastDFS分爲三個重要的部分,分別是客戶端(Client),跟蹤服務器(Tracker),儲存服務器(Strorage),,下面我一一爲你們介紹這三個角色github
儲存服務器:Storage Serverweb
主要的做用就是提供一個保存文件數據的空間,通常以Group爲一個單位,一個Group內包含多個Storage Server,看做是造成集羣吧,數據之間經過同步保持一致 [異步操做],做爲負載均衡的實現;多個Group之間互不聯繫,各自保存各自的數據,亦可造成集羣,由多個Group組成面試
跟蹤服務器:Tracker Servervim
看做是一個管理者吧,作一個調度中心,調度Client和Storege Server的通訊,在訪問上起負載均衡的做用數組
管理全部的Group,和Group中的全部的Storage Server,每個Storage在啓動後都會主動的鏈接Tracker,告知其所屬的Group和本身的運行狀態等信息,並保持心跳維持聯繫;
Tracker Server能夠造成集羣,對外提供服務,處理客戶端的請求採用輪詢的方式選擇Tracker進行處理
客服端:就是程序員編寫的程序
爲了支持大容量,儲存節點採用了分組的方式,儲存系統由一個或多個組組成,一個組能夠由一臺或多態儲存服務器組成,一個組下的多個Storage,的數據是同樣的,多個Storage起到了備份,防止單點故障,起到負載分攤的做用
若是咱們再想增長新的Storage到組內的時候,同步已有的文件由系統自動完成,同步完成後,系統自動將新增的服務切換到線上對外提供服務,可是這裏有個問題就是,當組內的儲存服務器的本地容量大小不一致時,該組的可容納文件數據上限以最小那個服務爲準,當組內的空間耗盡時,咱們能夠動態的添加一個新的組,只須要在組內增長一臺讀多態Storage,並將其配置爲咱們一個新的組,這樣就實現了了儲存容量的線性擴展
Storage會經過配置鏈接上集羣中的全部Tracker,定時向他們報告本身的狀態,包括"磁盤剩餘空間"、"文件同步情況"、"文件呢上傳下載次數"等統計信息
Storage一共有七個狀態,但咱們熟悉兩三個狀態就行:
FDFS-STORAGE-STATUS_ONLINE :服務在線,但沒有提供服務
FDFS-STORAGE-STATUS_ACTIVE :服務在線,能夠提供服務
FDFS-STORAGE-STATUS_OFFLINE:服務離線
0:Tracker Server收集Storage Server的狀態信息,Storage迴向全部的Tracker彙報本身的狀態,[空間狀況、文件同步狀況、上傳下載次數等信息]
1:Client想Tracker發起上傳請求,Client再上傳時可任意選擇一個集羣中的Tracker
2:當Tracker接收到上傳請求時,會爲該請求分配一個能夠儲存該文件的Group,一下幾種幾種選擇Group的規則
指定某一個Group
剩餘儲存空間最多的Group有限
輪詢的方式
2:當肯定了Group後,Storage會選擇一個Storage Server的ip和端口返回給客戶端,選取Storage支持如下的規則
在Group的範圍內輪詢
按照ip排序
按照在Storage上配置的優先級排序
3:客戶端訪問發起上傳請求,Storage將會爲這個上傳的文件分配一個數據儲存目錄,支持如下規則
多個儲存目錄之間輪詢
剩餘儲存空間最多的有限
3:選定了目錄以後,Storage會爲這個文件生成一個File_id,這個File_id的組成部分是包含了不少信息的,而後以這個File_id問文件名保存到選擇好的儲存目錄下
4:當文件已經儲存到選擇的目錄下的時候,即認爲該文件已經存在成功,接下來就會爲該文件另外生成一個標識文件名【用於定位】,該文件名包有Group、存儲目錄、子目錄、文件名、文件後綴名拼接而成並返回給客戶端,如這般模樣: group1/M00/00/00/Zad2afb5oaiuAZEMVABfYcN8vzII630.png
以前咱們就已經知道,一個Group組內的Storage是集羣狀態的,也就是當咱們將文件數據上傳到Storate後,會建立一個後臺線程將文件同步至同一個Group中的其餘的Storage Server.保持數據的一致性;
同步規則以下:
只在本組內的Storage Server之間同步;
源頭數據才須要同步,也就是該文件第一次上傳到那個Storage,那文件就成爲該Storage的源頭數據
當咱們新增Storage時,由已有全部數據的Storage將全部數據[源頭數據、備份數據]同步給新的新增服務器
當每一個Storage寫文件時,同時會寫一份binlog,可是這個binlog裏面不包含文件數據,只包含文件名等元信息,這封binlog用於後臺數據的同步,Storage會紀錄想Group內其餘Storage數據同步的進度,以便重啓後可以接上次的進度繼續同步,進度以時間戳的方式進行紀錄,因此最好能保證集羣內全部的Server的本地時間一致;[ Linux本地時間一致 ]
Storage的同步進度會做爲元數據的一部分報給給Tracker,Tracker在選擇讀取哪個Storage的時候就會以同步進度做爲參考:
初始化和第一步與文件上傳一致,特別要說的就是,以前咱們在文件上傳完成後,不是返回給客戶端一個標識文件名嗎,當咱們下載請求到達Tracker時候,Tracker會解析這個標識文件名,得到這個文件的Group,路徑信息,文件大小,建立時間,源Storage Server IP等消息,而後爲該請求響應一個Storage用來響應數據,
可是在選擇Storage的時候會有一個比較尷尬的狀況出現,那就是咱們要訪問的數據在咱們想獲取它的時候,尚未完成全Group內的數據同步,爲了不這種狀況的發生,Tracker在選擇可用Strage時經過必定的規則來選擇可讀的Storage,保證資源的可訪問性
三臺機器吧,一個做爲Tracker Server,兩臺做爲Storage
GCC用來對C語言代碼進行編譯運行,使用yum命令安裝:
sudo yum -y install gcc
unzip工具能夠幫咱們對壓縮包進行解壓
sudo yum install -y unzip zip
安裝libevent
sudo yum -y install libevent
安裝Nginx依賴
sudo yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel
安裝libfastcommon-master
這個沒有yum包,只能經過編譯安裝:
解壓剛剛上傳的libfastcommon-master.zip
unzip libfastcommon-master.zip
進入解壓完成的目錄:
cd libfastcommon-master
編譯而且安裝:
sudo ./make.sh
sudo ./make.sh install
下載FastDFS的
wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz
解壓、編譯、安裝
tar -zxvf V5.05.tar.gz
cd fastdfs-5.05
./make.sh
./make.sh install
經過上面的操做,咱們能夠經過 ll /etc/init.d/ | grep fdfs 獲取到兩個啓動腳本
fdfs_storaged 是storage啓動腳本
而後就是配置文件模版的檢查: ll /etc/fdfs/
storage.conf.sample 是storage的配置文件模板
client.conf.sample 是客戶端的配置文件模板
經過上面的查詢咱們能夠知道,安裝都是同樣的安裝,不區分Tracker 和 Storage,每一個安裝下都有Storage和Tracker的啓動命令,也有各自的配置文件,咱們就能夠修改相應的配置文件,運行相應的腳本便可開啓Tracker Server 和Storage Server
Tracker的話,咱們就修改 tracker.conf.sample配置文件,並啓動fdfs_trackerd腳本
編輯tracker的配置文件:進入到 /etc/fdfs/
cp tracker.conf.sample tracker.conf #實列配置文件重命名 vim tracker.conf #編輯該配置文件 #修改的內容:從新指定一個tracker的數據和日誌存放目錄 base_path=/usr/local/FastDFS/fdfsData # HTTP 服務端口,這個酌情修改,通常無需修改 http.server_port=80 #修改後保存退出,建立出咱們的這個文件夾 mkdir -p /usr/local/FastDFS/fdfsData
FastDFS的服務腳本在配置文件中指定的 /usr/local/bin,而實際命令是安裝在/usr/bin下的
若是就這樣啓動是找不到啓動腳本的,因此這裏有兩種解決方式:
第一種修改配置文件,從新指定服務腳本的路徑(不建議,容易出錯)
第二種方式就是創建軟鏈接 (推薦使用這種)
ln -s /usr/bin/fdfs_trackerd /usr/local/bin ln -s /usr/bin/fdfs_storaged /usr/local/bin #這個是tracker,無需配置storage軟鏈接 ln -s /usr/bin/stop.sh /usr/local/bin ln -s /usr/bin/restart.sh /usr/local/bin
而後咱們就能夠直接啓動Tracker Server了,啓動能夠用
#指定目錄下的腳本啓動,【不建議】 /etc/init.d/fdfs_trackerd start #安裝過程當中fdfs已是被設置爲系統服務,採用服務啓動方式【建議】 service fdfs_trackerd start #可用可不用,設置爲開機自啓 chkconfig fdfs_trackerd on # 或者 vim /etc/rc.d/rc.local ,加入配置設置爲開啓啓動: /etc/init.d/fdfs_trackerd start
查看FastDFS是否已經啓動:
netstat -ultp | grep fdfs 查詢到22122端口正在被監聽,視爲啓動成功
對應的此次咱們應該修改storage.conf並啓動fdfs_storage腳本便可完成Storage Server的開啓
首先咱們複製並重名配置文件
編輯storage.conf : 旁邊的編號是數據所在行數 : set nu
#配置storage的數據和日誌存放目錄 41 base_path=/usr/local/FastDFS/fdfsData #storage上傳文件的存放目錄 109 store_path0=/usr/local/FastDFS/storage #tracker的地址,端口默認便可,有多個Tracker,就複製這一排改ip port 便可 118 tracker_server=192.168.159.159:22122
而後就是建立配置文件中對應的目錄了:
mkdir -p /usr/local/FastDFS/fdfsData /usr/local/FastDFS/storage
再而後就是如法炮製,創建軟鏈接
ln -s /usr/bin/fdfs_trackerd /usr/local/bin #這個是storage,無需配置tracker軟鏈接 ln -s /usr/bin/fdfs_storaged /usr/local/bin ln -s /usr/bin/stop.sh /usr/local/bin ln -s /usr/bin/restart.sh /usr/local/bin
而後就能夠啓動了,在咱們啓動啓動Storage Server以前,必須確保Tracker是在線的
啓動方式也是如Tracker那般模樣有兩種,咱們採用系統服務啓動的方式
service fdfs_storaged start
而後查看一下監聽:netstat -ultp | grep fdfs
發現2300端口已被監控,算做是正常啓動
這個時候Storage Server 和Tracker Server算是已經創建裏鏈接了,咱們能夠去看看Storage Server存放上傳文件的目錄
能夠看到這些就是咱們用來存放上傳文件數據的目錄
基本環境算是搭建完成了,最後咱們還能夠查看一下整個系統的服務狀態:/usr/bin/fdfs_monitor /etc/fdfs/storage.conf
基本的環境就算搭建好了,咱們上傳的數據該如何才呢個被訪問呢?Nginx的靜態代理?仍是?
接着上面的咱們繼續,當咱們的圖片上傳後,該如何才能被外部說訪問呢,一個方案就是單獨的配置一個Nginx攔截對用的請求將其代理到咱們的FastDFS儲存數據的目錄便可,這種方式由於使用,因此不作過多說明,簡單帶過,留點筆記有個印象便可,注意Nginx是裝載Storage機器上的,不是Tracker機器上的,因此用Nginx指向指定的目錄文件,便可將本地的文件被外界經過Http請求所訪問到
首先你們要知道咱們的資源定位路徑,爲以下所示
這個時候咱們的Nginx的配置的話,就以下這樣:指向咱們存放數據的目錄
這種方式不是咱們學習的重點,下面這一種纔是咱們學習目標,FastDFS知道本身的文件不能被外界所訪問,本身集成了Nginx模塊到FastDFS中,須要咱們手工去發掘才能使用
首先簡單介紹一下FastDFS的Nginx模塊:
1、提供向外的http訪問服務
2、當Storage集羣下文件複製未完成的狀況下,請求訪問到了沒有複製完數據的機器,能夠將請求轉發到源服務器進行數據的獲取,能夠預防由於複製延遲致使的文件沒法訪問的錯誤【源服務器:就是該文件第一次上傳到Storage的那臺機器,而後才經過複製機制使得其餘Storage也有該文件的數據】
下載 fastdfs-nginx-module、解壓
# 下載 fastdfs-nginx-module wget https://github.com/happyfish100/fastdfs-nginx-module/archive/5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip # 解壓 unzip 5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip # 重命名 mv fastdfs-nginx-module-5e5f3566bbfa57418b5506aaefbe107a42c9fcb1 fastdfs-nginx-module-master
配置Nginx,在Nginx中添加模塊:
進入到解壓包目錄,咱們添加模塊後須要從新編譯、安裝【就是你下Nginx壓縮包解壓的那個文件夾】
這個過程看看頁面的信息有沒有什麼報錯信息error,沒有error視爲沒錯,可繼續
#進入到Nginx的解壓目錄 cd /root/nginx-1.10.2/ #添加模塊指定模塊src文件,個人模塊的位置是在 /usr/local/FastDFS/fastdfs-nginx-model-master/src ./configure --add-module=/usr/local/FastDFS/fastdfs-nginx-model-master/src #從新編譯並安裝 make && make install
查看模塊是否挖掘正確添加 進入到Nginx的安裝目錄: cd /usr/local/nginx/sbin
動用命令 : ./nginx -V, 以下則說明添加模塊成功
進入到Nginx模塊中,複製配置文件到指定文件:
cd /usr/local/FastDFS/fastdfs-nginx-model-master/src cp ./mod_fastdfs.conf /etc/fdfs/
要修改的部分屬性爲:
#鏈接超時時間 connect_timeout=10 #Tracker Server的配置 tracker_server=192.168.159.159:22122 #若是文件ID中包含、/group**,就要設爲True 52 url_have_group_name = true #Storage配置的Storage_path0的路徑,必須和/etc/fdfs/storage.conf中的路徑相同 61 store_path0=/usr/local/FastDFS/storage
複製部分配置文件到 /etc/fdfs/ 做爲系統配置文件
cd /usr/local/FastDFS/fastdfs-5.05/conf/ cp anti-steal.jpg http.conf mime.types /etc/fdfs/
而後就是配置Nginx的配置文件設置響應的location規則,以下:
#進入到Nginx的安裝目錄下的配置文件目錄,編譯nginx.conf
vim /usr/local/nginx/conf/nginx.conf
而後就是簡單的預檢一下配置文件是否完整,有沒有錯誤的地方 :nginx -tq
沒報錯就直接啓動 ./nginx ,而後發現以下頁面就算啓動成功:
咱們就在建立一個文件夾,存放咱們測試的圖片 mkdir /usr/local/FastDFS/testJPG
而後咱們本地拖一張帥照上去,利用FastDFS的內置上傳 演示一下文件上傳
在此以前咱們得將client.conf.sample重命名client.conf,並作修改:
# 調用測試 測試用的配置文件 上傳 上傳文件的路徑 /usr/bin/fdfs_test /etc/fdfs/client.conf upload /usr/local/FastDFS/testJPG/test.jpg
而後咱們就走Nginx的那臺服務器,經過Nginx去訪問這張圖片:
很差意思!跑錯片場了,因爲以前的Nginx我配不少東西,我把無關的都刪掉了,留下惟有的一個location和server,效果以下:
到這裏基本就完成了FastDFS的基本用法,後面還有點內容,容我慢慢更來
maven中央倉庫沒有這個依賴,須要咱們手動添加到本地Maven倉庫中
下載 :https://github.com/happyfish100/fastdfs-client-java
打成jar包,經過maven命令將該jar安裝在本地倉庫中
<dependencies>
<!--手動添加到本地庫的fdfs客戶端依賴-->
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>5.0.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!--測試依賴-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
編寫配置文件:fdfs_client.conf
tracker_server = 192.168.159.159:22122
而後就一個啓動函數
public class test { @Test public void test() throws Exception { // 一、加載配置文件,配置文件中的內容就是 tracker 服務的地址。
ClientGlobal.init("C:\\Users\\MSI\\Desktop\\code\\cloud-demo\\fdfsTest\\src\\main\\resources\\fdfs\\fdfs_client.conf"); // 二、建立一個 TrackerClient 對象。直接 new 一個。
TrackerClient trackerClient = new TrackerClient(); // 三、使用 TrackerClient 對象建立鏈接,得到一個 TrackerServer 對象。
TrackerServer trackerServer = trackerClient.getConnection(); // 四、建立一個 StorageServer 的引用,值爲 null
StorageServer storageServer = null; // 五、建立一個 StorageClient 對象,須要兩個參數 TrackerServer 對象、StorageServer 的引用
StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 六、使用 StorageClient 對象上傳圖片。 //擴展名不帶「.」
String[] strings = storageClient.upload_file("F:\\mySpace\\myPhoto\\beijing\\1.jpg", "jpg", null); // 七、返回數組。包含組名和圖片的路徑。
for (String string : strings) { System.out.println(string); } } }
最後咱們打印給咱們返回的路徑:
咱們就根據這個路徑去兩個Storage中查看數據是否存在,並在瀏覽器中經過Nginx去訪問它:
可見 以811結尾的文件正在兩臺Storage的數據目錄中,已經完成了同步,下面咱們去訪問它
OK,Java客戶端應該還有還有其餘的方式,不止這一種,後面若是遇到有與框架整合的,再作補充
婦聯網須要同一內容,可是不一樣尺寸的圖片,存儲壓縮圖就能知足這種需求
在學習這個以前沒咱們得知道什麼是"等比壓縮"?
好比源圖是1200*1200的 那麼縮略圖遵循等比壓縮,只能是1:1的縮略,好比300 * 300再或者700 * 700
而不能是500 * 600,再或者600 * 200,業務是不會這麼玩的
使用FastDFS儲存一個圖片的多個分辨率的備份時,但願只記住源圖的fileid,並能將其餘分辨率的圖片與源圖關聯,就是用到了儲存縮略圖這種方式,好比:
主從文件是指文件ID有關聯的文件,一個主文件能夠對應多個從文件
主文件ID = 主文件名 + 主文件擴展名
從文件ID = 主文件名 + 衝文件後綴名[好比_300*300] + 從文件擴展名
實現圖片壓縮有不少的方式,好比 ImageIO 、MagicImage、Nginx
固然Nginx是表現特別突出的,也就是咱們咱們今天的主要學習的;
image_filter模塊
Nginx的這個模塊針對"JPEG"、"GIF"、"PNG"類型圖片進行轉換處理[ 壓縮、裁剪、旋轉 ],這個模塊默認不被編譯,因此要在編譯Nginx源碼的時候就要加入相關的配置信息
安裝gd-devel依賴:
yum -y install gd-devel
從新編譯:以前還添加了部分模塊,我也找不到配置了,這裏肯恩而過有點偏差
sudo ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --add-module=/usr/local/FastDFS/fastdfs-nginx-model-master/src
編譯及安裝以及平滑重啓
make && make install
/usr/local/nginx/sbin/nginx -s reload
訪問普通的圖片
假設咱們的圖片的真是路徑是在本地的/usr/local/test/img/xxxx.jpg,下面有不少jgp格式的圖片,咱們但願經過訪問 、image/xxx_100 * 100.jpg這種請求生成長寬均爲100的小圖,而且請求的寬和高是隨着咱們的請求動態的改變的,那麼咱們就須要在Nginx模塊中攔截該請求並返回轉換後的小圖,在對應的server中配置,注意是× 而不是* ,我還繞進去了,
location ~* /img/(.*)_(\d+)×(\d+)\.(jpg|gif|png) { root /; set $s $1; set $w $2; set $h $3; set $t $4; image_filter resize $w $h; #從新設定大小,值應用請求url中的數值 image_filter_buffer 10M; #應該是緩存優化,還有不少的命令[百度],這裏我就作了最經常使用的壓縮 rewrite ^/img/(.*)$ /usr/local/test/img/$s.$t break; } #這裏對這個語法作個簡單的解釋,詳細的能夠百度查詢: # 拿這個請求作示範 :http://192.168.159.169/img/6_500x500.jpg
# set $s $1; $1是一個佔位符,表明請求中的第一個參數爲 6 # set $w $2; $2表明請求中的第二個參數 爲500 #以此類推,至關於就是經過佔位符獲取請求的的參數,將其賦值給一個變量。後面代碼可使用這個變量,作到值傳遞
當我這樣配置以後
rewrite命令可百度查詢用法,他最終指向的地址倒是Nginx安裝目錄下的 html/img/xx.jpg 這裏是x而不是*
一番錯誤日誌查看後,我被動的修改了個人圖片位置,隨後進行訪問,實現了縮略圖功能
至於訪問FastDFS的圖片資源:
Nginx配置下面的攔截規則和邏輯處理便可,實現整合FastDFS
[ 複製到文本刪掉註釋複製到配置文件中 ,避免格式錯亂]
location ~ /group1/M00/(.*)_([0-9]+)x([0-9]+)\.(jpg|gif|png){ alias /usr/local/FastDFS/storage/data; #指向資源所在路徑 ngx_fastdfs_module; #nginc的fdfs模塊 set $w $2; set $h $3; if ($h != "0") { #若是寬 = 0 重定向到另外一個路徑後退出 rewrite group1/M00(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ group1/M00$1.$4 break; } if ($w != "0") { #與上同理 rewrite /group1/M00/(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ /group1/M00/$1.$4 break; } image_filter crop $w $h; #根據給定的長度生成縮略圖 image_filter_buffer 2M; #源圖最大爲兩兆,要裁剪的圖片超過2M返回415錯誤 } location ~ group1/M00/(.+)\.?(.+){ alias /usr/local/FastDFS/storage/data; ngx_fastdfs_module; }
這個Nginx模塊主要功能就是對請求的圖片精心壓縮/水印處理,支持文字水印和圖片水印
支持自定義字體,文字大小水印透明度,水印位置;
判斷源圖是否大於制定儲存才處理等等共呢個
支持jpeg | png | gif 等格式
安裝步驟:
首先安裝相關的依賴
yum install -y gd-devel pcre-devel libcurl-devel
下載相關模塊並解壓
wget https://github.com/oupula/ngx_image_thumb/archive/master.tar.gztar -zxvf master.tar.gz
而後就是對Nginx從新編譯安裝,將這個模塊安裝進去:
sudo ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --add-module=/usr/local/FastDFS/fastdfs-nginx-model-master/src --add-module=/usr/local/FastDFS/ngx_image_thumb-master
而後就是修改Ngxin的配置文件,咱們把以前的那個模塊的攔接規則location刪掉,替換成這個模塊的:
location /test_image/ { root /usr/local/nginx/; image on; #是否開啓縮略圖功能,默認關閉off image_output on; #否不生成圖片而直接處理後輸出 默認off image_jpeg_quality 75; #生成JPEG圖片的質量 默認值75 image_water on; #是否開啓水印功能 image_water_type 0; #水印類型 0:圖片水印 1:文字水印 image_water_pos 9; #水印位置 默認值9 0爲隨機位置,1爲頂端居左,2爲頂端居中,3爲頂端居右,4爲中部居左,5爲中部居中,6爲中部居右,7爲底端居左,8爲底端居中,9爲底端居右 image_water_file "/usr/local/nginx/test_image/8.jpg"; #指定水印圖片的位置 image_water_transparent 80; #水印透明度,默認20 }
建立對應的文件夾和文件並上傳響應圖片資源到指定目錄
頗有不少的屬性,這裏就不作羅列了,能夠面向搜索引擎學習,而後就是查看咱們的結果:
經過這種方式,ip:port/xxx/x.jpg!c100x100.jpg 這種格式完成對圖片的加工並響應給客戶端
當咱們FastDFS在處理海量小文件的時候,文件系統的處理性能會受到顯著的影響,主要是IO的讀寫和接受併發的能力會有所降低,解決的方式就是合併儲存:將小文件合併儲存成大文件,使用seek來定位大文件的指定位置從而實現對小文件的訪問
FastDFS提供的合併儲存功能,默認建立的大文件爲64MB,而後再該大文件中儲存不少小文件,大文件中容納一個小文件的空間成爲一個Slot,規定Slot的最小值爲256KB,最大爲16MB,這裏須要說明的是,即便你的文件大小小於了256KB,但他仍是要佔256KB的空間,至於超過16MB的文件不會合並儲存而是建立獨立的文件
想要這個功能生效,咱們只須要在Tracker.conf中開啓和設置有關屬性的值便可
就這兩個屬性 修改一下便可,一個是開啓合併儲存,一個暫時我還明白是什麼意思,默認是0改成1便可
修改完以後就是殺掉當前Tracker的進程 ps -ef | grep tracker kill -9 XXXX
Tracker Server已經重啓完畢,再把兩個Storage Server 也重啓一下 [ 建議先kill,在運行 ]
而後咱們就用Java客戶端上傳兩張比較大的圖片測試一下, Java客戶端回顯:
M00/00/00/wKifqV0vRQyIUpxsACpHwg8v4b8AAAAAQAAAAAAKkfa715.jpg
M00/00/00/wKifqV0vSIOIIxiNAA_EXLIVQwwAAAAAQAqR9oAD8R0240.jpg
而後咱們去Storage中查看一下咱們上傳的文件:
咱們上傳的文件去哪了?我不知道,我也不敢問!
可是兩臺Storage Server 都多了一個0000001 並且大小還爲64M
當咱們對FastDFS上傳文件成功的時候,服務器會返回一個該文件的存取ID叫作fileid,當咱們沒有開啓合併儲存的時候,fileid和磁盤上實際儲存的文件一一對應,當咱們開啓了合併儲存以後,發現沒有對應的fileid了而是多個fileid被儲存成一個大文件
三個概念
Trunk文件:Storage服務器磁盤上儲存的實際文件,大小爲64M
00000001這種格式,文件名從1開始遞增,類型爲in
合併文件的fileid:服務器啓用合併儲存後,每次上傳返回給客戶端的fileid,可是已經沒有一一對應關係存在
沒有合併儲存的fileid:表示服務器未啓用合併儲存時,Upload返回的fileid
合併儲存後fileid的變化:
合併儲存:M00/00/00/wKifqV0vRQyIUpxsACpHwg8v4b8AAAAAQAAAAAAKkfa715.jpg
沒有合併:wKifqV0uV7WAX2K6AAJx98nYb9E811.jpg
有沒有發現什麼問題,長度?合併儲存以後返回的fileid明顯的比以前的要長不少,由於這個id中包含了不少的數據,重要的好比定位大文件的大文件id 和定位小文件的偏移量等
Trunk文件內部是由多個小文件組成,每一個小文件都會有一個trunkHeader,以及緊跟其後的真實上傳數據:
alloc_size : 文件大小與size等
filesize:該小文件佔用大文件的空間,最小256KB 最大16M
crc32:文件內容的crc32碼
mtime:文件的修改時間
formatted_ext_name:文件擴展名
Trunk文件的大小是64M,這個剛剛咱們已經看到了,這裏就涉及到一個空閒空間的問題,你想?當咱們儲存一個1M大小的文件時,咱們開啓了合併儲存,Trunk文件的大小是固定的64M,而咱們上傳所佔用的空間僅爲1M ,也就是說還有63M是空閒狀態的,當咱們下次再次上傳小於16M的文件時,空間的的獲取又是個什麼狀況呢?見圖知意:
我再作一個文字性的說明:
再Storage內部會爲每個store_path [ 配置文件中指定儲存數據的目錄 ]構造一棵一空閒空間塊大小做爲關鍵字的空閒平衡樹,大小相同的話,以鏈表形式存在,當我沒得上傳須要一個空間來儲存數據時,就會根據文件大小來匹配這棵樹,至於被匹配的那塊空間多餘的部分會被切割做爲一個新的空閒塊從新被掛在空閒平衡樹中
而後就會有一個問題發生:
一個組內的全部的Storage Server都具備分配空閒空間的能力,而咱們的請求是通過Tracker Server負載均衡分散請求,用一個Group內的Storage Server之間的一致性須要同步機制來完成,壞就壞在同步須要時間,而在這個同步的時間內,源數據所佔用的空間說不定已經被Tracker Server 分來的其餘儲存請求佔據,就會形成數據衝突,因而便引入了"TrunkServer" 的概念。
"Trunk Server ":是該Group中的一個Storage Server,Trunk Server由Tracker指定,只有Truncker Server纔有權限分配空閒的空間,決定文件應該保存在Trunkfile的哪一個位置,而且在經過trunk file(合併文件同步) + binlog日誌(空間分配同步)完成同步