FastDFS 的一系列踩坑
1. 什麼是 FastDFS
- FastDFS 由淘寶的餘慶大佬開源的一款輕量級分佈式文件管理系統
2. 爲什麼要使用 FastDFS
- 傳統的企業級開發對於高併發要求不是很高,而且數據量也不會很大,在這樣的環境下文件管理可能很簡單,但是互聯網應用訪問量大、數據量大,在互聯網就需要考慮解決文件大容量存儲和高性能訪問的問題,而 FastDFS 就適合幹這件事情,常見的圖片存儲、視頻存儲、文檔存儲等等都可以採用 FastDFS 來做。
3. FastDFS 安裝【CentOS】
- 圖片上傳功能使用 FastDFS,圖片上傳成功之後,接下來的圖片訪問我們一般採用 Nginx,所以需要安裝三個軟件包。
- Tracker 安裝
- Storage 安裝
- Nginx 安裝
3.1 Tracker 安裝
安裝,首先準備一個環境兩個庫以及一個安裝包。
【1. 一個環境】
因爲 FastDFS 採用 C 語言開發,安裝前,需要先安裝 gcc 環境。命令如下:
yum install gcc-c++
【2. 兩個庫】
由於 FastDFS 依賴 libevent 庫,安裝命令如下:
yum -y install libevent
另一個庫是 libfastcommon,這是 FastDFS 官方提供的,它包含了 FastDFS 運行所需要的一些基礎庫。
libfastcommon 下載地址,本人已經下載好,並不算很大,分享到了百度網盤,可以方便大家下載:百度網盤下載地址:提取碼:kpii
裏面提供的三個軟件都是必備的哦!
將下載好的 libfastcommon 拷貝至 /usr/local/ 目錄下,然後依次執行以下命令:
由於我們下到了本地,我們可以通過 Xftp 這個工具來將我們的安裝包【libfastcommon-1.0.43.tar.gz】拉到 CentOS 上面去。【當大家拉取完成後】
// 進入目錄中
cd /usr/local
// 對其解壓
tar -zxvf libfastcommon-1.0.43.tar.gz
// 解壓完進入文件夾中
cd libfastcommon-1.0.43
// 剩下的就是編譯安裝了
./make.sh
./make.sh install
【3. 一個安裝包】
網盤中已經分享,下載到本地後,通過 Xftp 將文件 【fastdfs-6.06.tar.gz】拷貝到 /usr/local 目錄下,然後依次執行以下命令安裝:
cd /usr/local
tar -zxvf fastdfs-6.06.tar.gz
cd fastdfs-6.06
./make.sh
./make.sh install
安裝成功後,執行如下命令,將安裝目錄內 conf 目錄下的配置文件拷貝到 /etc/fdfs目錄下:【目錄不用創建,cp 命令會幫你創建的】
cd conf/
cp ./* /etc/fdfs/
【4. 配置】
接下來進入 /etc/fdfs/ 目錄下進行配置:
打開 tracker.conf 文件:
cd /etc/fdfs/
vim tracker.conf
修改如下配置:
默認端口是 22122,可以跟據實際需求修改,然後再配置以下元數據的保存目錄(注意目錄要存在)。
【5. 啓動】
接下來執行如下命令啓動 Tracker:
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
3.2 Storage 安裝
Storage 本身的安裝和 Tracker 一致,執行命令都一樣,因爲這裏我將 Tracker 和 Storage 安裝再同一臺服務器上,所以不用再執行安裝命令了(相當於安裝了 Tracker 時已經安裝了 Storage 了)。
唯一要做的,就是進入到 /etc/fdfs 目錄下,配置 Storage:
cd /etc/fdfs/
vim storage.conf
這裏一共配置了三個地方,分別是 base_path、store_path0、tracker_server,tracker_server 模板有兩個地址,我們註釋一個,另一個修改成自己的虛擬機Ip。
配置完成後,再次啓動 Storage:
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
- 目前爲止,我們已經配置號 Tracker 和 Storage 了,並且二者都已經啓動了。這兩個啓動完成後,現在就可以做文件的上傳了,但是一般如果是圖片文件,我們還需要提供一個圖片的訪問功能,目前來說最佳方案是 Nginx。
- 我們先來測試看看 Tracker 和 Storage 配置的有沒有問題,看看文件上傳功能是否能夠跑通,當測試完全沒問題了,我們再去安裝 Nginx,再去實現訪問圖片的功能。
4. Java 客戶端測試
首先我們創建一個普通的 Mavne 工程,添加如下依賴:
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
然後,在項目的 resources 目錄下添加 FastDFS 的配置文件 fastdfs-client.properties,內容如下:
fastdfs.connect_timeout_in_seconds = 5
fastdfs.network_timeout_in_seconds = 30
fastdfs.charset = UTF-8
fastdfs.http_anti_steal_token = false
fastdfs.http_secret_key = FastDFS1234567890
fastdfs.http_tracker_http_port = 80
fastdfs.tracker_servers = 192.168.91.128:22122
fastdfs.connection_pool.enabled = true
fastdfs.connection_pool.max_count_per_entry = 500
fastdfs.connection_pool.max_idle_time = 3600
fastdfs.connection_pool.max_wait_time_in_ms = 1000
其中 fastdfs.tracker_servers 是 Tracker 的地址,大家跟據自己的虛擬機Ip配置即可。
4.1 文件上傳功能測試
代碼如下:
@Test
void contextLoads() throws IOException, MyException {
ClientGlobal.initByProperties("fastdfs-client.properties");
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
StorageServer storageServer = null;
StorageClient1 client1 = new StorageClient1(trackerServer, storageServer);
NameValuePair pairs[] = null;
String fileId = client1.upload_file1("C:\\Users\\bai\\Pictures\\Camera Roll\\img\\javaboy.jpg", "jpg", pairs);
System.out.println(fileId);
}
-
首先這裏加載配置文件,然後構造一個 TrackerClient 對象,接着再跟據這個對象獲取到一個 TrackerServer,然後再創建一個 StorageClient1 實例。NameValuePair 中保存的就是文件的元數據信息,如果有的話,就以 key/value 的方式來設置,如果沒有直接給一個 null 即可。
-
最後調用 client 的 upload_file1 方法上傳文件,第一個參數是文件路徑,第二個參數是文件的擴展名,第三個參數是文件的元數據信息,這個方法的返回值,就是上傳文件的訪問路徑,執行該方法,打印日誌如下:
-
group1/M00/00/00/wKj9gF6dngqASrBQAAAT8J10-TU753.jpg 就是文件的路徑,如果你的測試結果也是這樣就證明上傳文件的功能沒有問題。
5. Nginx 安裝
- 這時我們就可以通過安裝 Nginx 來完成訪問圖片的功能:
- Nginx 的安裝分爲兩個步驟:
- 安裝 Nginx
- 在 Storage 下安裝 fastdfs-nginx-module
5.1 安裝 Nginx【CentOS】
- 首先下載 Nginx
wget http://nginx.org/download/nginx-1.17.0.tar.gz
- 然後解壓下載的目錄,進入解壓目錄中,在編譯安裝之前,需要安裝兩個依賴:
yum -y install pcre-devel
yum -y install openssl openssl-devel
- 然後開始編譯安裝
./configure
make
make install
- 裝好之後,默認安裝位置在:
/usr/local/nginx/sbin/nginx
- 進入到該目錄的 sbin 目錄下,執行 nginx 即可啓動 nginx【我們這裏先不要啓動nginx】
5.2 安裝 fastdfs-nginx-module
【百度網盤已經下載好的】,將下載好的文件拷貝到 /usr/local 目錄下,進入 /usr/local 目錄,分別執行如下命令:
cd /usr/local
tar -zxvf fastdfs-nginx-module-1.22.tar.gz
然後將 /usr/local/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf 文件拷貝到 /etc/fdfs 目錄下,並修改文件的內容:
cp /usr/local/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf /etc/fdfs/
vim /etc/fdfs/mod_fastdfs.conf
- 接下來,回到第一步下載的 nginx 安裝文件的解壓目錄中,執行如下命令,重新配置編譯安裝:
./configure --add-module=/usr/local/fastdfs-nginx-module-1.22/src
make
make install
- 安裝完成後,修改 nginx 的配置文件,如下:
vim /usr/local/nginx/conf/nginx.conf
- 在這裏配置 nginx 請求轉發。
- 配置完成後,啓動 nginx ,看到如下日誌,表示 nginx 啓動成功:
// 首先進入 nginx 的目錄中去
cd /usr/local/nginx/sbin/
// 啓動 nginx
./nginx
// 啓動成功後的打印日誌
ngx_http_fastdfs_set pid=20932
全部安裝成功了。
6. Java 客戶端訪問圖片測試
- 由於上面我們已經完成了文件上傳的功能,並且拿到了文件Id,也就是如下圖所示:
- 此時在瀏覽器中輸入http://192.168.91.128/group1/M00/00/00/wKj9gF6dkA-AeHQ1AAAT8J10-TU507.jpg 就可以看到上傳的圖片了。
7. 文件下載
@Test
void download() throws IOException, MyException {
ClientGlobal.initByProperties("fastdfs-client.properties");
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
StorageServer storageServer = null;
StorageClient1 client1 = new StorageClient1(trackerServer, storageServer);
byte[] bytes = client1.download_file1("group1/M00/00/00/wKj9gF6da6yAU-EMAAAT8J10-TU390.jpg");
FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\bai\\Pictures\\Camera Roll\\img\\javaboy2.jpg"));
fos.write(bytes);
fos.close();
}
-代碼解釋:直接調用 download_file1 方法獲取到一個 byte 數組,然後通過 IO 流寫出到本地文件即可。
8. 安全問題
- 現在任何人都能訪問我們服務器上的文件,這肯定不安全,在上傳的時候加上令牌即可。
- 首先我們在服務端開啓令牌校驗:
vim /etc/fdfs/http.conf
- 配置完成後,重啓服務器:
./nginx -s stop
./nginx
- 接下來,準備一個獲取令牌的方法,如下:
@Test
void getToken() throws UnsupportedEncodingException, NoSuchAlgorithmException, MyException {
int ts = (int) Instant.now().getEpochSecond();
String token = ProtoCommon.getToken("M00/00/00/wKj9gF6dkA-AeHQ1AAAT8J10-TU507.jpg", ts, "FastDFS1234567890");
StringBuilder sb = new StringBuilder();
sb.append("http://192.168.253.128")
.append("/group1/M00/00/00/wKj9gF6dkA-AeHQ1AAAT8J10-TU507.jpg")
.append("?token=")
.append(token)
.append("&ts=")
.append(ts);
System.out.println(sb.toString());
}
- 這裏我們主要是跟據 ProtoCommon.getToken 方法來獲取令牌,注意這個方法的第一個參數就是你要訪問的文件 id,注意,這個地址裏邊不要包含 group,千萬別搞錯了,第二個參數是時間戳,第三個參數是密鑰,密鑰要和服務端的配置一致。
- 此時我們運行此方法,然後控制檯打印一個路徑,我們就可以點擊去訪問了【如果此時將路徑中的 token去掉,就會訪問失敗,默認展示的就是 nginx 的錯誤頁面】。
9. 踩坑過程【22122端口沒有開放】
如果你的配置文件沒有問題,但是發生連接不上 22122 這個端口的話,原因就是你的 防火牆沒有開發 22122 着端口號,只要你開啓了 22122 端口號就能避免這個錯誤了。