文章大綱
一尾膊、FastDFS介紹
二媳危、FastDFS安裝與啟動(Linux系統(tǒng))
三、Java客戶端上傳圖片
四冈敛、參考文章
一待笑、FastDFS介紹
1. 什么是FastDFS
FastDFS是用C語言編寫的一款開源的分布式文件系統(tǒng)。FastDFS為互聯(lián)網(wǎng)量身定制抓谴,充分考慮了冗余備份暮蹂、負載均衡、線性擴容等機制齐邦,并注重高可用椎侠、高性能等指標(biāo),使用FastDFS很容易搭建一套高性能的文件服務(wù)器集群提供文件上傳措拇、下載等服務(wù)我纪。
2. FastDFS架構(gòu)
FastDFS架構(gòu)包括 Tracker server和Storage server
??Tracker server作用是對Storage server進行負載均衡和調(diào)度,在文件上傳時會直接請求Tracker server丐吓,然后Tracker server可以根據(jù)一些策略找到Storage server來提供文件上傳服務(wù)浅悉。所以可以將tracker稱為追蹤服務(wù)器或調(diào)度服務(wù)器。
??Storage server作用是文件存儲券犁,客戶端上傳的文件最終存儲在Storage服務(wù)器上术健,Storage server沒有實現(xiàn)自己的文件系統(tǒng)而是利用操作系統(tǒng)的文件系統(tǒng)來管理文件≌吵模可以將storage稱為存儲服務(wù)器荞估。
??具體架構(gòu)如下圖:
2.1 Tracker 集群
FastDFS集群中的Tracker server可以有多臺咳促,Tracker server之間是相互平等關(guān)系同時提供服務(wù),Tracker server不存在單點故障勘伺」蚋梗客戶端請求Tracker server采用輪詢方式,如果請求的tracker無法提供服務(wù)則換另一個tracker飞醉。
2.2 Storage集群
??Storage集群采用了分組存儲方式冲茸。storage集群由一個或多個組構(gòu)成,一個組由一臺或多臺存儲服務(wù)器組成缅帘,組內(nèi)的Storage server之間是平等關(guān)系轴术,不同組的Storage server之間不會相互通信,同組內(nèi)的Storage server之間會相互連接進行文件同步钦无,從而保證同組內(nèi)每個storage上的文件完全一致的逗栽。一個組的存儲容量為該組內(nèi)存儲服務(wù)器容量最小的那個,集群存儲總?cè)萘繛榧褐兴薪M的存儲容量之和铃诬,由此可見組內(nèi)存儲服務(wù)器的軟硬件配置最好是一致的祭陷。
??采用分組存儲方式的好處是靈活、可控性較強趣席。比如上傳文件時,可以由客戶端直接指定上傳到的組也可以由tracker進行調(diào)度選擇醇蝴。一個分組的存儲服務(wù)器訪問壓力較大時宣肚,可以在該組增加存儲服務(wù)器來擴充服務(wù)能力(縱向擴容)。當(dāng)系統(tǒng)容量不足時悠栓,可以增加組來擴充存儲容量(橫向擴容)霉涨。
2.3 文件上傳流程
客戶端上傳文件后存儲服務(wù)器將文件ID返回給客戶端,此文件ID用于以后訪問該文件的索引信息惭适。文件索引信息包括:組名笙瑟,虛擬磁盤路徑,數(shù)據(jù)兩級目錄癞志,文件名往枷。
上傳說明
(1)組名:文件上傳后所在的storage組名稱,在文件上傳成功后有storage服務(wù)器返回凄杯,需要客戶端自行保存错洁。
(2)虛擬磁盤路徑:storage配置的虛擬路徑,與磁盤選項store_path*對應(yīng)戒突。如果配置了store_path0則是M00屯碴,如果配置了store_path1則是M01,以此類推膊存。
(3)數(shù)據(jù)兩級目錄:storage服務(wù)器在每個虛擬磁盤路徑下創(chuàng)建的兩級目錄导而,用于存儲數(shù)據(jù)文件忱叭。
(4)文件名:與文件上傳時不同。是由存儲服務(wù)器根據(jù)特定信息生成今艺,文件名包含:源存儲服務(wù)器IP地址窑多、文件創(chuàng)建時間戳、文件大小洼滚、隨機數(shù)和文件拓展名等信息埂息。
2.4 文件下載流程
tracker根據(jù)請求的文件路徑即文件ID 來快速定義文件。
比如請求下邊的文件:
下載說明
(1)通過組名tracker能夠很快的定位到客戶端需要訪問的存儲服務(wù)器組是group1遥巴,并選擇合適的存儲服務(wù)器提供客戶端訪問千康。
(2)存儲服務(wù)器根據(jù)“文件存儲虛擬磁盤路徑”和“數(shù)據(jù)文件兩級目錄”可以很快定位到文件所在目錄,并根據(jù)文件名找到客戶端需要訪問的文件铲掐。
二拾弃、FastDFS安裝與啟動(Linux系統(tǒng))
1. 安裝libfastcommon
(1)獲取libfastcommon安裝包:
獲取libfastcommon安裝包:
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.38.tar.gz
(2)解壓安裝包:tar -zxvf V1.0.38.tar.gz
(3)進入目錄:cd libfastcommon-1.0.38
(4)執(zhí)行編譯:./make.sh
(5)安裝:./make.sh install
(6)可能遇到的問題
-bash: make: command not found
-bash: gcc: command not found
解決方案:
debian通過apt-get install gcc make安裝
centos通過yum -y install gcc make安裝
2. 安裝FastDFS
(1)獲取fdfs安裝包:
wget https://github.com/happyfish100/fastdfs/archive/V5.11.tar.gz
(2)解壓安裝包:tar -zxvf V5.11.tar.gz
(3)進入目錄:cd fastdfs-5.11
(4)執(zhí)行編譯:./make.sh
(5)安裝:./make.sh install
(6)查看可執(zhí)行命令:ls -la /usr/bin/fdfs*
3. 配置Tracker服務(wù)
(1)進入/etc/fdfs目錄,有三個.sample后綴的文件(自動生成的fdfs模板配置文件)摆霉,通過cp命令拷貝tracker.conf.sample豪椿,刪除.sample后綴作為正式文件:
(2)編輯tracker.conf:vi tracker.conf,修改相關(guān)參數(shù)
base_path=/home/mm/fastdfs/tracker #tracker存儲data和log的跟路徑携栋,必須提前創(chuàng)建好
port=23000 #tracker默認23000
http.server_port=80 #http端口搭盾,需要和nginx相同
(3)啟動tracker(支持start|stop|restart):
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
(4)查看tracker啟動日志:進入剛剛指定的base_path(/home/mm/fastdfs/tracker)中有個logs目錄,查看tracker.log文件
(5)查看端口情況:netstat -apn|grep fdfs
(6)可能遇到的報錯
/usr/bin/fdfs_trackerd: error while loading shared libraries: libfastcommon.so: cannot open shared object file: No such file or directory
解決方案:建立libfastcommon.so軟鏈接
ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
4. 配置Storage服務(wù)
(1)進入/etc/fdfs目錄婉支,有cp命令拷貝storage.conf.sample鸯隅,刪除.sample后綴作為正式文件;
(2)編輯storage.conf:vi storage.conf,修改相關(guān)參數(shù):
base_path=/home/mm/fastdfs/storage #storage存儲data和log的跟路徑向挖,必須提前創(chuàng)建好
port=23000 #storge默認23000蝌以,同一個組的storage端口號必須一致
group_name=group1 #默認組名,根據(jù)實際情況修改
store_path_count=1 #存儲路徑個數(shù)何之,需要和store_path個數(shù)匹配
store_path0=/home/mm/fastdfs/storage #如果為空跟畅,則使用base_path
tracker_server=10.122.149.211:22122 #配置該storage監(jiān)聽的tracker的ip和port
(3)啟動storage(支持start|stop|restart)
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
(4)查看storage啟動日志:進入剛剛指定的base_path(/home/mm/fastdfs/storage)中有個logs目錄,查看storage.log文件
(5)此時再查看tracker日志:發(fā)現(xiàn)已經(jīng)開始選舉溶推,并且作為唯一的一個tracker徊件,被選舉為leader
(6)查看端口情況:netstat -apn|grep fdfs
(7)通過monitor來查看storage是否成功綁定
/usr/bin/fdfs_monitor /etc/fdfs/storage.conf
5. 安裝Nginx和fastdfs-nginx-module模塊
(1)下載Nginx安裝包
wget http://nginx.org/download/nginx-1.15.2.tar.gz
(2)下載fastdfs-nginx-module安裝包
wget https://github.com/happyfish100/fastdfs-nginx-module/archive/V1.20.tar.gz
(3)解壓nginx:tar -zxvf nginx-1.15.2.tar.gz
(4)解壓fastdfs-nginx-module:tar -xvf V1.20.tar.gz
(5)進入nginx目錄:cd nginx-1.10.1
(6)安裝依賴的庫
apt-get update
apt-get install libpcre3 libpcre3-dev openssl libssl-dev libperl-dev
(7)配置,并加載fastdfs-nginx-module模塊:
./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/fastdfs-nginx-module-1.20/src/
(8)編譯安裝:
make
make install
(9)查看安裝路徑:whereis nginx
- 啟動悼潭、停止:
cd /usr/local/nginx/sbin/
./nginx
./nginx -s stop #此方式相當(dāng)于先查出nginx進程id再使用kill命令強制殺掉進程
./nginx -s quit #此方式停止步驟是待nginx進程處理任務(wù)完畢進行停止
./nginx -s reload
(11)驗證啟動狀態(tài):wget "http://127.0.0.1"
(12)查看此時的nginx版本:發(fā)現(xiàn)fastdfs模塊已經(jīng)安裝好了
(13)可能的報錯
/usr/include/fastdfs/fdfs_define.h:15:27: fatal error: common_define.h: No such file or directory
解決方案:修改fastdfs-nginx-module-1.20/src/config文件庇忌,然后重新第7步開始
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
6. 配置Nginx和fastdfs-nginx-module模塊
(1)配置mod-fastdfs.conf,并拷貝到/etc/fdfs文件目錄下
cd fastdfs-nginx-module-1.20/src/
cp mod_fastdfs.conf /etc/fdfs
(2)進入/etc/fdfs修改mod-fastdfs.conf
base_path=/home/mm/fastdfs
tracker_server=10.122.149.211:22122 #tracker的地址
url_have_group_name=true #url是否包含group名稱
storage_server_port=23000 #需要和storage配置的相同
store_path_count=1 #存儲路徑個數(shù)舰褪,需要和store_path個數(shù)匹配
store_path0=/home/mm/fastdfs/storage #文件存儲的位置
(3)配置nginx皆疹,80端口server增加location如圖
cd /usr/local/nginx/conf/
vi nginx.conf
(4)最后需要拷貝fastdfs解壓目錄中的http.conf和mime.types
cd /usr/local/src/fastdfs-5.11/conf
cp mime.types http.conf /etc/fdfs/
7. FastDFS常用命令測試
7.1 上傳文件
(1)進入/etc/fdfs目錄,有cp命令拷貝client.conf.sample占拍,刪除.sample后綴作為正式文件;
(2)修改client.conf相關(guān)配置:
base_path=/home/mm/fastdfs/tracker //tracker服務(wù)器文件路徑
tracker_server=10.122.149.211:22122 //tracker服務(wù)器IP地址和端口號
http.tracker_server_port=80 # tracker服務(wù)器的http端口號略就,必須和tracker的設(shè)置對應(yīng)起來
(3)新建一個測試文檔1.txt捎迫,內(nèi)容為abc
(4)命令
/usr/bin/fdfs_upload_file <config_file> <local_filename>
(5)示例
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf 1.txt
組名:group1
磁盤:M00
目錄:00/00
文件名稱:CnqV01trmeyAbAN0AAAABLh3frE677.txt
(6)查看結(jié)果,進入storage的data目錄
(7)通過wget和瀏覽器方式訪問成功
wget http://10.122.149.211/group1/M00/00/00/CnqV01trmeyAbAN0AAAABLh3frE677.txt
7.2 下載文件
(1)命令
/usr/bin/fdfs_download_file <config_file> <file_id> [local_filename]
(2)示例
/usr/bin/fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/CnqV01trmeyAbAN0AAAABLh3frE677.txt a.txt
(3)查看結(jié)果
7.3 刪除文件
(1)命令
/usr/bin/fdfs_delete_file <config_file> <file_id>
(2)示例
/usr/bin/fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/CnqV01trmeyAbAN0AAAABLh3frE677.txt
(3)查看結(jié)果表牢,進入storage的data目錄文件不存在窄绒,通過wget再次獲取404:
溫馨提示:現(xiàn)在FastDFS的安裝好像不支持Windows
三、Java客戶端上傳圖片
1. 新建maven項目
2. pom.xml文件添加相關(guān)依賴
<dependencies>
<!--引入FastDFS工具類-->
<dependency>
<groupId>cn.bestwu</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27</version>
</dependency>
<!--引入testng單元測試-->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
</dependency>
<!--引入IO工具類庫-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
3. 添加配置文件內(nèi)容
connect_timeout = 2
network_timeout = 30
charset = UTF-8
# Tracker配置文件中配置的http端口
http.tracker_http_port = 80
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
# Tracker服務(wù)器地址
tracker_server = 192.168.105.133:22122
tracker_server = 192.168.105.134:22122
4. 創(chuàng)建Java_Tools類崔兴,使用單元測試測試文件上傳和下載
import org.apache.commons.io.IOUtils;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.testng.annotations.Test;
import java.io.FileOutputStream;
import java.io.IOException;
public class Java_Tools {
// 本地文件位置
String local = "C:\\Users\\XY\\Documents\\上傳.txt";
// 聲明跟蹤器客戶端對象
TrackerClient trackerClient = null;
// 聲明存儲器客戶端對象
StorageClient1 storageClient1 = null;
// 聲明跟蹤器服務(wù)對象
TrackerServer trackerServer = null;
// 聲明存儲器服務(wù)對象
StorageServer storageServer = null;
// 文件上傳
@Test
public void testUpload() {
try {
// 初始化配置文件
ClientGlobal.init("fdfs_client.conf");
// 創(chuàng)建跟蹤器客戶端對象
trackerClient = new TrackerClient();
// 獲取跟蹤器連接
trackerServer = trackerClient.getConnection();
// 獲取存儲器客戶端對象
storageClient1 = new StorageClient1(trackerServer, storageServer);
// 上傳文件彰导,返回文件標(biāo)識
String index = storageClient1.upload_file1(local, null, null);
// 查看標(biāo)識
System.out.println(index);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
// 文件下載
@Test
public void testDownload() {
try {
ClientGlobal.init("fdfs_client.conf");
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageClient1 = new StorageClient1(trackerServer, storageServer);
// 根據(jù)文件標(biāo)識下載文件
byte[] by = storageClient1.download_file1("group1/M00/00/00/wKhphVrxnTeAPEznAANfM1yHJic535.txt");
// 將數(shù)據(jù)寫入輸出流
IOUtils.write(by, new FileOutputStream("C:\\Users\\XY\\Documents\\下載.txt"));
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
// 文件刪除
@Test
public void testDelete() {
try {
ClientGlobal.init("fdfs_client.conf");
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageClient1 = new StorageClient1(trackerServer, storageServer);
// 根據(jù)文件標(biāo)識刪除文件,返回0則刪除成功
int i = storageClient1.delete_file1("group1/M00/00/00/wKhphVry2QmAXgH2AANfM1yHJic724.txt");
if (i == 0) {
System.out.println("刪除成功");
} else {
System.out.println("刪除失敗");
}
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
// 文件信息
@Test
public void testGetFileInfo() {
try {
ClientGlobal.init("fdfs_client.conf");
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageClient1 = new StorageClient1(trackerServer, storageServer);
// 根據(jù)文件標(biāo)識獲取文件信息
FileInfo fileInfo = storageClient1.get_file_info1("group1/M00/00/00/wKhphVry2QmAXgH2AANfM1yHJic724.txt");
// 文件IP地址
System.out.println(fileInfo.getSourceIpAddr());
// 文件大小
System.out.println(fileInfo.getFileSize());
// 創(chuàng)建時間
System.out.println(fileInfo.getCreateTimestamp());
// 錯誤校驗碼
System.out.println(fileInfo.getCrc32());
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
}