FastDFS——分佈式文件存儲

FastDFS—分佈式文件存儲

1. 什麼是FastDFS

​ FastDFS是一個開源的輕量級分佈式文件系統,它對文件進行管理,功能包括:文件存儲、文件同步、文件訪問(文件上傳、文件下載)等,解決了大容量存儲和負載均衡的問題。

2. FastDFS 的組成

  • FastDFS 架構包括 Tracker server 和 Storage server。

客戶端請求 Tracker server 進行文件上傳、下載,通過Tracker server 調度最終由 Storage server 完成文件上傳和下載。

  • Tracker server 作用是負載均衡和調度,通過 Tracker server 在文件上傳時可以根據一些策略找到Storage server 提供文件上傳服務。可以將 tracker 稱爲追蹤服務器或調度服務器。

  • Storage server 作用是文件存儲,客戶端上傳的文件最終存儲在 Storage 服務器上,Storageserver 沒有實現自己的文件系統而是利用操作系統的文件系統來管理文件。可以將storage稱爲存儲服務器。

3. 搭建FastDFS文件存儲微服務

  1. 引入依賴
<dependencies> 
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring‐boot‐starter‐web</artifactId>
    </dependency>
	<dependency>
		<groupId>net.oschina.zcx7878</groupId>
        <artifactId>fastdfs‐client‐java</artifactId>
        <version>1.27.0.0</version>
	</dependency>
</dependencies>
  1. 在resources文件夾下創建fasfDFS的配置文件fdfs_client.conf
connect_timeout = 60 # 連接超時時間,單位爲秒。
network_timeout = 60 # 通信超時時間,單位爲秒。
charset = UTF‐8 # 字符集
http.tracker_http_port = 8080  # tracker的http端口
tracker_server = 192.168.200.128:22122  # tracker服務器IP和端口設置
  1. 在resources文件夾下創建application.yml
spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
  application:
    name: file
server:
  port: 9008
  1. 創建啓動類FileApplication
@SpringBootApplication
public class FileApplication {
	public static void main(String[] args) {
		SpringApplication.run(FileApplication.class);
	}
}
  1. 準備一個封裝文件的實體類
package com.xm.file.pojo;

/**
 * @title: FileApplication
 * @projectName: changgou-parent
 * @description: TODO
 * @author: Zack_Tzh
 * @date: 2019/12/8  14:15
 */
public class FastDFSFile {
    //文件名字
    private String name;
    //文件內容
    private byte[] content;
    //文件擴展名
    private String ext;
    //文件MD5摘要值
    private String md5;
    //文件創建作者
    private String author;

    public FastDFSFile(String name, byte[] content, String ext, String height,
                       String width, String author) {
        super();
        this.name = name;
        this.content = content;
        this.ext = ext;
        this.author = author;
    }

    public FastDFSFile(String name, byte[] content, String ext) {
        super();
        this.name = name;
        this.content = content;
        this.ext = ext;
    }

//    set get  。。。
  1. FastDFS工具類:FastDFSClient類
package com.xm.file.util;

import com.xm.file.pojo.FastDFSFile;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @title: FileApplication
 * @projectName: changgou-parent
 * @description: TODO
 * @author: Zack_Tzh
 * @date: 2019/12/8  15:15
 */
public class FastDFSClient {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(FastDFSClient.class);

    /***
     * 初始化加載FastDFS的TrackerServer配置
     */
    static {
        try {
            String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
            ClientGlobal.init(filePath);
        } catch (Exception e) {
            logger.error("FastDFS Client Init Fail!",e);
        }
    }

    /***
     * 文件上傳
     * @param file
     * @return
     */
    public static String[] upload(FastDFSFile file) {
        //獲取文件的作者
        NameValuePair[] meta_list = new NameValuePair[1];
        meta_list[0] = new NameValuePair("author", file.getAuthor());

        //接收返回數據
        String[] uploadResults = null;
        StorageClient storageClient=null;
        try {
            //創建StorageClient客戶端對象
            storageClient = getTrackerClient();

            /***
             * 文件上傳
             * 1)文件字節數組
             * 2)文件擴展名
             * 3)文件作者
             */
            uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
        } catch (Exception e) {
            logger.error("Exception when uploadind the file:" + file.getName(), e);
        }

        if (uploadResults == null && storageClient!=null) {
            logger.error("upload file fail, error code:" + storageClient.getErrorCode());
        }
        //獲取組名
        String groupName = uploadResults[0];
        //獲取文件存儲路徑
        String remoteFileName = uploadResults[1];
        return uploadResults;
    }

    /***
     * 獲取文件信息
     * @param groupName:組名
     * @param remoteFileName:文件存儲完整名
     * @return
     */
    public static FileInfo getFile(String groupName, String remoteFileName) {
        try {
            StorageClient storageClient = getTrackerClient();
            return storageClient.get_file_info(groupName, remoteFileName);
        } catch (Exception e) {
            logger.error("Exception: Get File from Fast DFS failed", e);
        }
        return null;
    }

    /***
     * 文件下載
     * @param groupName
     * @param remoteFileName
     * @return
     */
    public static InputStream downFile(String groupName, String remoteFileName) {
        try {
            //創建StorageClient
            StorageClient storageClient = getTrackerClient();

            //下載文件
            byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
            InputStream ins = new ByteArrayInputStream(fileByte);
            return ins;
        } catch (Exception e) {
            logger.error("Exception: Get File from Fast DFS failed", e);
        }
        return null;
    }

    /***
     * 文件刪除
     * @param groupName
     * @param remoteFileName
     * @throws Exception
     */
    public static void deleteFile(String groupName, String remoteFileName) throws Exception {
        //創建StorageClient
        StorageClient storageClient = getTrackerClient();

        //刪除文件
        int i = storageClient.delete_file(groupName, remoteFileName);
    }

    /***
     * 獲取Storage組
     * @param groupName
     * @return
     * @throws IOException
     */
    public static StorageServer[] getStoreStorages(String groupName) throws IOException {
        //創建TrackerClient
        TrackerClient trackerClient = new TrackerClient();
        //獲取TrackerServer
        TrackerServer trackerServer = trackerClient.getConnection();
        //獲取Storage組
        return trackerClient.getStoreStorages(trackerServer, groupName);
    }

    /***
     * 獲取Storage信息,IP和端口
     * @param groupName
     * @param remoteFileName
     * @return
     * @throws IOException
     */
    public static ServerInfo[] getFetchStorages(String groupName, String remoteFileName) throws IOException {
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
    }

    /***
     * 獲取Tracker服務地址
     * @return
     * @throws IOException
     */
    public static String getTrackerUrl() throws IOException {
        return "http://"+getTrackerServer().getInetSocketAddress().getHostString()+":"+ClientGlobal.getG_tracker_http_port()+"/";
    }

    /***
     * 獲取Storage客戶端
     * @return
     * @throws IOException
     */
    private static StorageClient getTrackerClient() throws IOException {
        TrackerServer trackerServer = getTrackerServer();
        StorageClient storageClient = new StorageClient(trackerServer, null);
        return  storageClient;
    }

    /***
     * 獲取Tracker
     * @return
     * @throws IOException
     */
    private static TrackerServer getTrackerServer() throws IOException {
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        return  trackerServer;
    }
}
  1. 創建Controller接收文件並上傳到FastDFS上
package com.xm.file.controller;

import com.xm.file.pojo.FastDFSFile;
import com.xm.file.util.FastDFSClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;


/**
 * @title: FileController
 * @projectName: changgou-parent
 * @description: TODO
 * @author: Zack_Tzh
 * @date: 2019/12/8  18:45
 */
@RestController
@RequestMapping("/xm/v1/file")
public class FileController {

    @RequestMapping("/upload")
    public String upload(MultipartFile file) {
        try {
            //獲取原始文件名
            String originalFilename = file.getOriginalFilename();
            //獲取文件後綴
            String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            //文件數據
            byte[] data = file.getBytes();

            //創建文件上傳的封裝實體類
            FastDFSFile fastDFSFile = new FastDFSFile(originalFilename, data, ext);
			//用FastDFSClient工具類上傳文件
            String[] uploadResults = FastDFSClient.upload(fastDFSFile);
            //拼接文件訪問地址
            String url = FastDFSClient.getTrackerUrl() + uploadResults[0] +"/"+ uploadResults[1];
            System.out.println(url);
            return url;
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上傳失敗";
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章