SpringBoot集成FastDFS實(shí)現(xiàn)防盜鏈功能
關(guān)于FastDFS
FastDFS是一個(gè)高性能的分布式?件系統(tǒng)。
FastDFS是由Tracker server(追蹤調(diào)度服務(wù)器) 和 Storage server(文件存儲(chǔ)服務(wù)器)組成。
Storage server(文件存儲(chǔ)服務(wù)器)又是由多個(gè)組構(gòu)成
Tracker server(追蹤調(diào)度服務(wù)器)Tracker server(追蹤調(diào)度服務(wù)器),作?是負(fù)載均衡和調(diào)度,通過 Tracker server 在?件上傳時(shí)可以根據(jù)?些策略找到Storage server 提供?件上傳服務(wù),所以將 tracker server稱為追蹤服務(wù)器或調(diào)度服務(wù)器。
Storage server(文件存儲(chǔ)服務(wù)器)Storage server(文件存儲(chǔ)服務(wù)器) 作?是?件存儲(chǔ),客戶端上傳的?件最終存儲(chǔ)在 Storage 服務(wù)器上,Storage server 沒有實(shí)現(xiàn)??的?件系統(tǒng)?是利?操作系統(tǒng)的?件系統(tǒng)來管理?件,所以將storage稱為存儲(chǔ)服務(wù)器。
Group(組)
1.由于Storage server(文件存儲(chǔ)服務(wù)器)是用來存儲(chǔ)文件的,具有容量限制,為了解決該問題,提出擴(kuò)容分組,所以延伸出組的概念。
2.每個(gè)組存放部分文件,且每個(gè)組之間保存的?件是不同的。
3.為保證每個(gè)組內(nèi)的節(jié)點(diǎn)服務(wù)高可用,允許組內(nèi)構(gòu)建存儲(chǔ)服務(wù)器集群,每個(gè)組內(nèi)部可以有多個(gè)成員,組成員內(nèi)部保存的內(nèi)容是?樣的,組成員的地位是?致的,沒有主從的概念。
4.由于文件存放在每個(gè)組的節(jié)點(diǎn)上,所以為了方便http訪問調(diào)用,每個(gè)Storage server還要綁定一個(gè)nginx。
5.所有的組加起來是一個(gè)完成的Storage server(文件存儲(chǔ)服務(wù)器)。
docker安裝FastDFS
1.安裝步驟
拉取fastdfs鏡像
docker pull delron/fastdfs
創(chuàng)建Tracker server(追蹤調(diào)度服務(wù)器)容器
提示:在指定虛擬機(jī)鏡像之后,還需要添加tracker命令,這樣鏡像就會(huì)根據(jù)tracker命令啟動(dòng)tracker服務(wù)
docker run -d --name tracker --net=host -p 22122:22122 -v /var/fastdfs/tracker:/var/fdfs delron/fastdfs tracker
–net=host : 將虛擬機(jī)的網(wǎng)絡(luò)應(yīng)用于容器,也就是說和宿主機(jī)網(wǎng)絡(luò)一致
Storage server(文件存儲(chǔ)服務(wù)器),需要指定Tracker 的ip和端口
提示:在指定虛擬機(jī)鏡像之后,還需要添加storager命令,這樣鏡像就會(huì)根據(jù)storage命令啟動(dòng)storage服務(wù)
docker run -d --name storage --net=host -p 8888:8888 -p 23000:23000 -e TRACKER_SERVER=192.168.130.160:22122 -e GROUP_NAME=group1 -v /var/fastdfs/storage:/var/fdfs delron/fastdfs storage
GROUP_NAME=group1 : 指定服務(wù)器在組group1中或者新增一個(gè)組叫g(shù)roup1,如果想要增加新的組用于擴(kuò)容 ,再次運(yùn)行該命令,更換新組名即可。
–net=host : 將虛擬機(jī)的網(wǎng)絡(luò)應(yīng)用于容器,也就是說和宿主機(jī)網(wǎng)絡(luò)一致
2.修改nginx配置
storage內(nèi)部已經(jīng)集成了nginx,這里的nginx可以使圖片在瀏覽器中訪問到
進(jìn)入Storage容器內(nèi)
提示:進(jìn)入Storage容器內(nèi)【cd /etc/fdfs/ 】也有Storage和Tracker的配置
docker exec -it storage /bin/bash
編輯文件【nginx.conf】文件
vi /usr/local/nginx/conf/nginx.conf

如果i進(jìn)行了配置修改 則需要重啟
docker restart storage
使用步驟
1.導(dǎo)包
<!--fastdfs文件存儲(chǔ)-->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.7</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>2.添加配置
在【application.yml】添加配置
fdfs:
so-timeout: 1500 #讀取超時(shí)時(shí)間
connect-timeout: 600 #連接超時(shí)時(shí)間
thumb-image: #縮略圖參數(shù)
width: 150
height: 150
tracker-list: 192.168.136.160:22122 #tracker服務(wù)器地址 可配置多個(gè)
web-server-url: http://192.168.136.160:8888 #訪問路徑 storage中nginx地址
測(cè)試
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.server.AppServerApplication;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.File;
import java.io.IOException;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppServerApplication.class)
public class FastDFSTest {
@Autowired
protected FastFileStorageClient storageClient;
@Autowired
private FdfsWebServer fdfsWebServer;
@Test
public void testUpload() {
String path = "D:\\IMAGE\\2e8e06bd-bfe3-4af3-9540-83eb20982656.jpg";
File file = new File(path);
try {
//上傳圖片
StorePath storePath = this.storageClient.uploadFile(FileUtils.openInputStream(file), file.length(), "jpg", null);
//拼接路徑 可通過該路徑訪問上傳的照片 http://192.168.136.160:8888/group1/M00/00/00/wKiIoGMB7PmAUPZZAAHMYGEwMhg147.jpg
String url = fdfsWebServer.getWebServerUrl() + "/" + storePath.getFullPath();
System.out.println(url);
} catch (IOException e) {
e.printStackTrace();
}
}
}fastdfs開啟防盜鏈功能
實(shí)現(xiàn)原理
1.fastdfs是一個(gè)分布式文件系統(tǒng),如果我們的fastdfs部署在外網(wǎng),那么任何一個(gè)人知道了我們的上傳接口,那么它就可以文件的上傳和訪問。那么我們?nèi)绾巫柚顾嗽L問我們fastdfs服務(wù)器上的文件呢?因此就需要使用fastdfs的防盜鏈功能。
2.原理:fastdfs的防盜鏈?zhǔn)峭ㄟ^token機(jī)制來實(shí)現(xiàn)的。當(dāng)我們開啟防盜鏈功能后,需要在url后增加2個(gè)額外的參數(shù)token和ts。token和ts的生成都是需要在服務(wù)端。
開啟防盜鏈
FastDFS擴(kuò)展模塊內(nèi)置了通過token來實(shí)現(xiàn)防盜鏈的功能。開啟防盜鏈后,訪問文件是需要在url中加兩個(gè)參數(shù):token和ts。ts為時(shí)間戳,token為系統(tǒng)根據(jù)時(shí)間戳和密碼生成的信物。
進(jìn)入 storage 容器 打開:
vi /etc/fdfs/http.conf
# true 表示開啟防盜鏈 http.anti_steal.check_token = true # token的過期時(shí)間,單位為秒 http.anti_steal.token_ttl = 300 # 密鑰,不可泄漏,用于生成token http.anti_steal.secret_key = thisisasecuritykey # 當(dāng)圖片拒絕訪問后,顯示的圖片,此圖片需要可訪問,不然可能會(huì)出現(xiàn)問題,放到容器里 使用 chmod -R 777 /data/fastdfs/404.jpg 授權(quán) http.anti_steal.token_check_fail = /data/fastdfs/404.jpg
http.anti_steal.token_check_fail 指定的圖片需要可訪問,否則可能會(huì)出現(xiàn)問題,可以對(duì)應(yīng) storage 容器的 nginx 日志查看,包括調(diào)試網(wǎng)絡(luò)
重啟nginx
/usr/local/nginx/sbin/nginx -s reload
Java代碼生成授權(quán)token
1.token生成規(guī)則
token = md5(文件ID+私鑰+時(shí)間戳) 文件ID:不能包含group
group1/M00/00/00/wKh5iWNBl7-AKvj1AAAwWD4VeAg577.jpg `需要替換成` M00/00/00/wKh5iWNBl7-AKvj1AAAwWD4VeAg577.jpg
私鑰:需要和 /etc/fdfs/http.conf 中的 http.anti_steal.secret_key 值一致
時(shí)間戳:單位秒
2.java生成token
/**
* 生成防盜鏈token
* @param remoteFilename 文件路徑,不帶group:M00/00/00/wKg4C1tFmTWAFPKBAADdeFFxlXA240.png
* @param httpHost 文件服務(wù)器web訪問地址
* @param secretKey 密碼
* @return
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
* @throws MyException
*/
public static String getSourceUrl(String remoteFilename, String httpHost,String secretKey) throws UnsupportedEncodingException, NoSuchAlgorithmException, MyException {
int lts = (int)(System.currentTimeMillis() / 1000);
String token = ProtoCommon.getToken(remoteFilename, lts, secretKey); //初始化secret_key
return httpHost + "/" + remoteFilename + "?token=" + token + "&ts=" + lts;
}
/**
* 獲取分組id
*
* @param fileUrl 文件地址
* @return 分組id
*/
public static String getGroupId(String fileUrl) {
if (fileUrl.indexOf("/group") == 0) {
fileUrl = fileUrl.substring(fileUrl.indexOf("/") + 1);
} else if (fileUrl.contains("http")) {
int index = fileUrl.indexOf("group");
if (index != -1) {
fileUrl = fileUrl.substring(index);
}
} else {
int index = fileUrl.indexOf("group");
if (index != -1) {
fileUrl = fileUrl.substring(index);
}
}
return fileUrl;
}得到
http://192.168.56.10:8888/M00/00/00/wKg4C1tFmTWAFPKBAADdeFFxlXA240.png?token=2fd428c6acc14126239e3a7d7d1d872b&ts=153
測(cè)試
正確的token請(qǐng)求

錯(cuò)誤的token請(qǐng)求

問題
1. 實(shí)現(xiàn)了文件上傳,但是通過Nginx去訪問文件就報(bào)錯(cuò)請(qǐng)求出現(xiàn):ERROR - file: ../fastdfs-nginx-module/src/common.c errno: 13, error info: Permission denied
解決辦法:
對(duì)storage的新掛載的data2(本系統(tǒng)新建的文件夾是data2)賦權(quán)限。執(zhí)行命令 chmod -R 777 data2/ 即可,最好是777
2.fastdfs的常見錯(cuò)誤:getStoreStorage fail, errno code: 0,getStoreStorage fail, errno code:2@TOC
解決辦法:
首先看先注冊(cè)中心配置的文件地址與服務(wù)器中/etc/fdfs/storage.conf的地址是否一致


2.如果以上配置正確且一致,重啟tracker和重啟storage
重啟命令:
tracker:fdfs_trackerd /etc/fdfs/tracker.conf restartstorage:fdfs_storaged /etc/fdfs/storage.conf restart
參考:詳解SpringBoot實(shí)現(xiàn)fastdfs防盜鏈功能的示例代碼
以上就是SpringBoot集成FastDFS實(shí)現(xiàn)防盜鏈功能的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot FastDFS防盜鏈的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring的同一個(gè)服務(wù)會(huì)加載多次的問題分析及解決方法
這篇文章主要介紹了Spring的同一個(gè)服務(wù)為什么會(huì)加載多次,我們先來梳理一下?Web?容器中如何加載?Bean,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
java?Object的hashCode方法的計(jì)算邏輯分析
這篇文章主要介紹了java?Object的hashCode方法的計(jì)算邏輯分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
SpringBoot或SpringAI對(duì)接DeepSeek大模型的詳細(xì)步驟
這篇文章主要介紹了DeepSeek智能助手的使用方法和步驟,包括引入庫、配置環(huán)境變量和配置,文章詳細(xì)描述了流式請(qǐng)求和非流式請(qǐng)求的實(shí)現(xiàn)方式,需要的朋友可以參考下2025-02-02
IDEA右鍵新建時(shí)沒有Java Class選項(xiàng)的解決過程
今天遇到在IntelliJ IDEA中無法新建JavaClass文件的問題,經(jīng)過查詢和實(shí)踐,找到了兩種解決辦法,第一種是避免將包名設(shè)置為Java的關(guān)鍵字,例如將"abstract"改為"abstract_";第二種是通過Project Structure設(shè)置Sources目錄,將包含Java類的目錄標(biāo)記為Sources2025-11-11
SpringBoot集成tomcat詳解實(shí)現(xiàn)過程
采用spring boot之后,一切變得如此簡單,打包->java-jar->運(yùn)維,只需要一個(gè)jar包便可以隨意部署安裝。這篇文章,將對(duì) spring boot集成tomcat的源碼進(jìn)行分析,探索其內(nèi)部的原理2023-02-02

