02.fastDFS分布式文件上傳下載解決方案

fastDFS 分布式文件上傳解決方案

一、fastDFS介紹

1). 特點(diǎn)

c 語言編寫的一款開源的分布式文件系統(tǒng);充分考慮了冗余備份、負(fù)載均衡、線性擴(kuò)容等機(jī)制,并注重高可用、高性能等指標(biāo),使用 FastDFS很容易搭建一套高性能的文件服務(wù)器集群提供文件上傳、下載等服務(wù)

2). 架構(gòu)

FastDFS 架構(gòu)包括 Tracker serverStorage server??蛻舳苏埱?Tracker server 進(jìn)行文件上傳、下載,通過 Tracker server 調(diào)度最終由 Storage server 完成文件上傳和下載。

Tracker server 作用是負(fù)載均衡和調(diào)度,通過 Tracker server 在文件上傳時可以根據(jù)一些策略找到 Storage server 提供文件上傳服務(wù)。可以將 tracker 稱為追蹤服務(wù)器或調(diào)度服務(wù)器。

Storage server 作用是文件存儲,客戶端上傳的文件最終存儲在 Storage 服務(wù)器上,Storageserver 沒有實(shí)現(xiàn)自己的文件系統(tǒng)而是利用操作系統(tǒng) 的文件系統(tǒng)來管理文件??梢詫torage稱為存儲服務(wù)器。

3). 服務(wù)端的兩個角色


fastDFS1.png

1. Tracker:管理集群,tracker 也可以實(shí)現(xiàn)集群。每個 tracker 節(jié)點(diǎn)地位平等。收集 Storage 集群的狀態(tài)。

2. Storage:實(shí)際保存文件 Storage 分為多個組,每個組之間保存的文件是不同的。每個組內(nèi)部可以有多個成員,組成員內(nèi)部保存的內(nèi)容是一樣的,組成員的地位是一致的,沒有主從的概念。

二、文件上傳下載

1). 上傳流程


文件上傳時序圖.png

客戶端上傳文件后存儲服務(wù)器將文件 ID 返回給客戶端,此文件 ID 用于以后訪問該文件的索引信息。文件索引信息包括:組名,虛擬磁盤路徑,數(shù)據(jù)兩級目錄,文件名。
group1/M00/02/44/wKgDrE34E8wAAAAAGxx.xx

  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)建時間戳、文件大小、隨機(jī)數(shù)和文件拓展名等信息。

2). 下載流程


文件下載時序圖.png

3). 最簡單的fastDFS架構(gòu)


最簡單的fastDFS架構(gòu).png

四、FastDFS安裝

推薦請有經(jīng)驗(yàn)的運(yùn)維開發(fā)人員安裝!開發(fā)中如果使用的為別人配置好的虛擬器,請一定要選擇 我已移動該虛擬機(jī)!, 否則會出現(xiàn)配置問題!

FastDFS安裝部署

密碼:oox9; 依賴jar包也在分享的文件中!maven中央倉庫沒有,需要手動安裝到本地倉庫或者私服

mvn install:install-file -DgroupId=org.csource.fastdfs -DartifactId=fastdfs  -Dversion=1.2 -Dpackaging=jar -Dfile=d:\setup\fastdfs_client_v1.20.jar

五、FastDFS使用案例

1). 項目結(jié)構(gòu)圖


fastDFS使用案例.png
  1. Controller
package com.lingting.controller;

import com.lingting.utils.FastDFSClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/** 文件上傳解析器 */
@RestController
@RequestMapping("/file")
public class UploadController {

    /** 這里的依賴注入 在 springMVC中已經(jīng)配置了,寫了這個注解
     * 框架會自動將對應(yīng)值進(jìn)行注入 */
    @Value("${FILE_SERVER_URL}")
    private String FILE_SERVER_URL;

    @RequestMapping("/upload")
    public String upload(MultipartFile file) {

        // 1. 取文件的擴(kuò)展名
        String originalFilename = file.getOriginalFilename();
        String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        try {
            // 2. 創(chuàng)建一個FastDFS的客戶端, FastDFS 類是封裝好的一個工具類,將fastDFS的接口封裝好了
            FastDFSClient fastDFSClient = new FastDFSClient("classpath:fdfs_client.conf");

            // 3. 執(zhí)行上傳處理
            String path = fastDFSClient.uploadFile(file.getBytes(), extName);

            // 4. 拼接返回的url和ip地址,拼裝成完整的url
            String url = FILE_SERVER_URL + path;
            System.out.println(url);
            return url;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "null";
    }
}
  1. utils
package com.lingting.utils;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

public class FastDFSClient {

    private TrackerClient trackerClient = null;
    private TrackerServer trackerServer = null;
    private StorageServer storageServer = null;
    private StorageClient1 storageClient = null;

    public FastDFSClient(String conf) throws Exception {
        if (conf.contains("classpath:")) {
            conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
        }
        ClientGlobal.init(conf);
        trackerClient = new TrackerClient();
        trackerServer = trackerClient.getConnection();
        storageServer = null;
        storageClient = new StorageClient1(trackerServer, storageServer);
    }

    /**
     * 上傳文件方法
     * <p>Title: uploadFile</p>
     * <p>Description: </p>
     * @param fileName 文件全路徑
     * @param extName 文件擴(kuò)展名,不包含(.)
     * @param metas 文件擴(kuò)展信息
     * @return
     * @throws Exception
     */
    public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
        String result = storageClient.upload_file1(fileName, extName, metas);
        return result;
    }

    public String uploadFile(String fileName) throws Exception {
        return uploadFile(fileName, null, null);
    }

    public String uploadFile(String fileName, String extName) throws Exception {
        return uploadFile(fileName, extName, null);
    }

    /**
     * 上傳文件方法
     * <p>Title: uploadFile</p>
     * <p>Description: </p>
     * @param fileContent 文件的內(nèi)容,字節(jié)數(shù)組
     * @param extName 文件擴(kuò)展名
     * @param metas 文件擴(kuò)展信息
     * @return
     * @throws Exception
     */
    public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {

        String result = storageClient.upload_file1(fileContent, extName, metas);
        return result;
    }

    public String uploadFile(byte[] fileContent) throws Exception {
        return uploadFile(fileContent, null, null);
    }

    public String uploadFile(byte[] fileContent, String extName) throws Exception {
        return uploadFile(fileContent, extName, null);
    }
}

  1. fdfs_client.conf
# connect timeout in seconds
# default value is 30s
connect_timeout=30

# network timeout in seconds
# default value is 30s
network_timeout=60

# the base path to store log files
base_path=/home/fastdfs

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=192.168.25.133:22122

#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false

# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600

# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false

# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false

# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf


#HTTP settings
http.tracker_server_port=80

#use "#include" directive to include HTTP other settiongs
##include http.conf
  1. application.properties
FILE_SERVER_URL=http://192.168.25.133/
  1. springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 此配置會解析對應(yīng)路徑下的配置文件的內(nèi)容,在需要使用的地方可以使用注解注入的方式進(jìn)行注入! -->
    <context:property-placeholder location="classpath:application.properties" />
    <!-- 配置掃面包 -->
    <context:component-scan base-package="com.lingting.controller"/>
    <!-- 開啟注解支持 -->
    <mvc:annotation-driven/>
    <!-- 配置多媒體解析器,id值固定,不能隨便取,框架規(guī)定的! -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"/>
        <!-- 設(shè)定文件上傳的最大值5MB, 5 * 1024 * 1024 -->
        <property name="maxUploadSize" value="5242880"/>
    </bean>
</beans>
  1. web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
    <!-- 解決post亂碼 -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 指定加載的配置文件 ,通過參數(shù)contextConfigLocation加載-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>
  1. index.html
<form action="file/upload.do" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <button type="submit">文件上傳</button>
</form>
  1. pom.xml依賴
<packaging>war</packaging>

<dependencies>
    <!-- Spring相關(guān) -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>

    <!-- fastdfs以及文件上傳相關(guān) -->
    <dependency>
        <groupId>org.csource.fastdfs</groupId>
        <artifactId>fastdfs</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

六、FastDFS獨(dú)立小Demo

1). 項目結(jié)構(gòu)


fastDFSDemo.png

2). 代碼

  1. pom.xml依賴
<packaging>jar</packaging>
<dependencies>
    <dependency>
        <groupId>org.csource.fastdfs</groupId>
        <artifactId>fastdfs</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>
  1. fdfs_client.conf配置文件
connect_timeout=30
network_timeout=60
base_path=/home/fastdfs
tracker_server=192.168.25.133:22122
log_level=info
use_connection_pool = false
connection_pool_max_idle_time = 3600
load_fdfs_parameters_from_tracker=false
use_storage_id = false
storage_ids_filename = storage_ids.conf
http.tracker_server_port=80
  1. FastDFSDemo
import org.csource.fastdfs.*;

/**
 * FastDFS 入門案例
 * */
public class FastDFSDemo {

    public static void main(String[] args) throws Exception{

        // 1. 加載配置文件,配置文件的內(nèi)容就是tracker服務(wù)的地址
        ClientGlobal.init("E:\\JavaWebSSMWorkspaces\\pinyougou\\fastDFSDemo\\src\\main\\resources\\fdfs_client.conf");

        // 2. 創(chuàng)建一個TrackerClient對象。
        TrackerClient trackerClient = new TrackerClient();

        // 3. 使用TrackerClient對象創(chuàng)建連接,獲得一個TrackServer對象
        TrackerServer trackerServer = trackerClient.getConnection();

        // 4. 創(chuàng)建一個StorageServer的引用,值為null
        StorageServer storageServer = null;

        // 5、創(chuàng)建一個 StorageClient 對象,需要兩個參數(shù) TrackerServer 對象、StorageServer 的引用
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);

        // 6、使用 StorageClient 對象上傳圖片。擴(kuò)展名不帶“.”

        String[] strings = storageClient.upload_file("G:\\圖片\\4K\\117068_original_5760x3240.jpg", "jpg", null);

        // 7、返回數(shù)組。包含組名和圖片的路徑。
        for (String string : strings) {
            System.out.println(string);
        }

    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容