springboot整合FastDFS使用實現防盜鏈功能

快乐小洋人發表於2024-06-25

關於FastDFS

FastDFS是一個高效能的分散式⽂件系統。
FastDFS是由Tracker server(追蹤排程伺服器) 和 Storage server(檔案儲存伺服器)組成。
Storage server(檔案儲存伺服器)又是由多個組構成

Tracker server(追蹤排程伺服器)
Tracker server(追蹤排程伺服器),作⽤是負載均衡和排程,透過 Tracker server 在⽂件上傳時可以根據⼀些策略找到Storage server 提供⽂件上傳服務,所以將 tracker server稱為追蹤伺服器或排程伺服器。

Storage server(檔案儲存伺服器)
Storage server(檔案儲存伺服器) 作⽤是⽂件儲存,客戶端上傳的⽂件最終儲存在 Storage 伺服器上,Storage server 沒有實現⾃⼰的⽂件系統⽽是利⽤作業系統的⽂件系統來管理⽂件,所以將storage稱為儲存伺服器。

Group(組)

1.由於Storage server(檔案儲存伺服器)是用來儲存檔案的,具有容量限制,為了解決該問題,提出擴容分組,所以延伸出組的概念。
2.每個組存放部分檔案,且每個組之間儲存的⽂件是不同的。
3.為保證每個組內的節點服務高可用,允許組內構建儲存伺服器叢集,每個組內部可以有多個成員,組成員內部儲存的內容是⼀樣的,組成員的地位是⼀致的,沒有主從的概念。
4.由於檔案存放在每個組的節點上,所以為了方便http訪問呼叫,每個Storage server還要繫結一個nginx。
5.所有的組加起來是一個完成的Storage server(檔案儲存伺服器)。

docker安裝FastDFS

  • 1.安裝步驟

1.拉取fastdfs映象

docker pull delron/fastdfs

2.建立Tracker server(追蹤排程伺服器)容器

提示:在指定虛擬機器映象之後,還需要新增tracker命令,這樣映象就會根據tracker命令啟動tracker服務

docker run -d --name tracker --net=host -p 22122:22122 -v /var/fastdfs/tracker:/var/fdfs delron/fastdfs tracker

–net=host : 將虛擬機器的網路應用於容器,也就是說和宿主機網路一致

3.Storage server(檔案儲存伺服器),需要指定Tracker 的ip和埠

提示:在指定虛擬機器映象之後,還需要新增storager命令,這樣映象就會根據storage命令啟動storage服務

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 : 指定伺服器在組group1中或者新增一個組叫group1,如果想要增加新的組用於擴容 ,再次執行該命令,更換新組名即可。
–net=host : 將虛擬機器的網路應用於容器,也就是說和宿主機網路一致

  • 2.修改nginx配置

storage內部已經整合了nginx,這裡的nginx可以使圖片在瀏覽器中訪問到

1.進入Storage容器內

提示:進入Storage容器內【cd /etc/fdfs/ 】也有Storage和Tracker的配置

docker exec -it storage /bin/bash

2.編輯檔案【nginx.conf】檔案

vi /usr/local/nginx/conf/nginx.conf

3.如果i進行了配置修改 則需要重啟

docker restart storage

使用步驟

1.導包

<!--fastdfs檔案儲存-->
<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 #讀取超時時間
  connect-timeout: 600 #連線超時時間
  thumb-image: #縮圖引數
    width: 150
    height: 150
  tracker-list: 192.168.136.160:22122 #tracker伺服器地址 可配置多個
  web-server-url: http://192.168.136.160:8888 #訪問路徑 storage中nginx地址

測試

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開啟防盜鏈功能

實現原理

1.fastdfs是一個分散式檔案系統,如果我們的fastdfs部署在外網,那麼任何一個人知道了我們的上傳介面,那麼它就可以檔案的上傳和訪問。那麼我們如何阻止他人訪問我們fastdfs伺服器上的檔案呢?因此就需要使用fastdfs的防盜鏈功能。

2.原理:fastdfs的防盜鏈是透過token機制來實現的。當我們開啟防盜鏈功能後,需要在url後增加2個額外的引數token和ts。token和ts的生成都是需要在服務端。

開啟防盜鏈

FastDFS擴充套件模組內建了透過token來實現防盜鏈的功能。開啟防盜鏈後,訪問檔案是需要在url中加兩個引數:token和ts。ts為時間戳,token為系統根據時間戳和密碼生成的信物。

進入 storage 容器 開啟:

vi /etc/fdfs/http.conf

# true 表示開啟防盜鏈
http.anti_steal.check_token = true
# token的過期時間,單位為秒
http.anti_steal.token_ttl = 300
# 金鑰,不可洩漏,用於生成token
http.anti_steal.secret_key = thisisasecuritykey
# 當圖片拒絕訪問後,顯示的圖片,此圖片需要可訪問,不然可能會出現問題,放到容器裡 使用 chmod -R 777 /data/fastdfs/404.jpg 授權
http.anti_steal.token_check_fail = /data/fastdfs/404.jpg

http.anti_steal.token_check_fail 指定的圖片需要可訪問,否則可能會出現問題,可以對應 storage 容器的 nginx 日誌檢視,包括除錯網路

重啟nginx

/usr/local/nginx/sbin/nginx -s reload

Java程式碼生成授權token

1.token生成規則

token = md5(檔案ID+私鑰+時間戳) 檔案ID:不能包含group

group1/M00/00/00/wKh5iWNBl7-AKvj1AAAwWD4VeAg577.jpg
`需要替換成`
M00/00/00/wKh5iWNBl7-AKvj1AAAwWD4VeAg577.jpg

私鑰:需要和 /etc/fdfs/http.conf 中的 http.anti_steal.secret_key 值一致
時間戳:單位秒

2.java生成token

   /**
     * 生成防盜鏈token
     * @param remoteFilename 檔案路徑,不帶group:M00/00/00/wKg4C1tFmTWAFPKBAADdeFFxlXA240.png
     * @param httpHost         檔案伺服器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

測試

正確的token請求

錯誤的token請求

問題

1.實現了檔案上傳,但是透過Nginx去訪問檔案就報錯請求出現:ERROR - file: ../fastdfs-nginx-module/src/common.c** errno: 13, error info: Permission denied

解決辦法:對storage的新掛載的data2(本系統新建的資料夾是data2)賦許可權。執行命令 chmod -R 777 data2/ 即可,最好是777


原文章地址:
https://blog.csdn.net/z13615480737/article/details/134134293
https://blog.csdn.net/packge/article/details/126451355

相關文章