FastDFS学习笔记

堵德曜
2023-12-01

FastDFS学习笔记

1.FastDFS安装步骤

1.0.环境准备

  • CentOS 7.5
  • libfastcommon-v1.0.7.tar.gz
  • fastdfs-v5.05.tar.gz
  • fastdfs-nginx-module-1.20.tar.gz(直接见错误解决方案)
  • nginx-v1.15.1.tar.gz

1.1.开始搭建

1.1.1.nginx安装(后面要用)

这里看我的博文:Nginx安装步骤

1.1.2.fastDFS安装

1、创建 fast_dfs 目录,并进到 fast_dfs 目录中,下载所需的安装包

mkdir /usr/apps/fast_dfs
cd /usr/apps/fast_dfs

## 下载libfastcommon v1.0.7
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz

## 下载FastDFS v5.05
wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz

## 下载fastdfs-nginx-module v1.20
wget https://codeload.github.com/happyfish100/fastdfs-nginx-module/tar.gz/refs/tags/V1.20 -O fastdfs-nginx-module-1.20.tar.gz

### fastdfs-nginx-module 备份(后续加入nginx时make出错使用)
wget https://github.com/happyfish100/fastdfs-nginx-module/archive/5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip

2、安装 libfastcommon v1.0.7

# 解压安装libfastcommon v1.0.7
tar -xvf V1.0.7.tar.gz
cd /usr/apps/fast_dfs/libfastcommon-1.0.7
## 编译、安装
./make.sh
./make.sh install
## 创建软连接
ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
ln -s /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so
ln -s /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so

3、安装FastDFS

# 解压安装FastDFS V5.05
cd /usr/apps/fast_dfs
tar -xvf V5.05.tar.gz
cd fastdfs-5.05

## 编译、安装
./make.sh
./make.sh install

4、配置 fastdfs 的 tracker 服务

问:为什么是配置 fastdfs 的 tracker 服务,而不是 fastdfs 服务?
答:因为 fastdfs 是有两个服务模块组成的,分别是 tracker、storage(tracker 为 storage 的支持)。

上述安装成功后,在 /etc/ 目录下会有一个 fdfs 的目录。在它当中会看到三个 .sample 后缀的文件,这是是示例文件,把其中的 tracker.conf.sample 文件复制一份命名为 tracker.conf,配置并修改 tracker.conf 配置文件。

cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
vim /etc/fdfs/tracker.conf ## 注需要安装vim命令,没有使用vi命令

编辑 tracker.conf

# 配置文件是否不生效,false 为生效
disabled=false
# 提供服务的端口
port=22122
# Tracker 数据和日志目录地址
base_path=/home/data/fastdfs
# HTTP服务端口80(方便后续集成nginx代理--猜测(滑稽))
http.server_port=80

创建 tracker 基础数据目录,即 base_path 对应的目录

mkdir -p /home/data/fastdfs

使用 ln -s 建立软链接

ln -s /usr/bin/fdfs_trackerd /usr/local/bin
ln -s /usr/bin/stop.sh /usr/local/bin
ln -s /usr/bin/restart.sh /usr/local/bin

tracker 服务管理

# 启动、停止、重启
service fdfs_trackerd start
service fdfs_trackerd stop
service fdfs_trackerd restart

# 查看启动监听
netstat -unltp|grep fdfs

注:如果看到22122端口正常被监听后,这时候说明 tracker 服务启动成功。

tracker server 目录及文件结构 tracker 服务启动成功后,会在 base_path 下创建 data、logs 两个目录。目录结构如下:

${base_path}
  |__data
  |   |__storage_groups.dat  #存储分组信息
  |   |__storage_servers.dat #存储服务器列表
  |__logs
  |   |__trackerd.log        #tracker server日志文件 

4、配置 fastdfs 的 storage 服务

进入 /etc/fdfs 目录,复制 fastDFS 存储器样例配置文件 storage.conf.sample,并重命名为 storage.conf:

cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
vim /etc/fdfs/storage.conf ## 注需要安装vim命令,没有使用vi命令

编辑 storage.conf:

# 配置文件是否不生效,false 为生效
disabled=false
# 指定此 storage server 所在组(卷)
group_name=group1
# storage server 服务端口
port=23000
# 心跳间隔时间,单位为秒 (这里是指主动向 tracker server 发送心跳)
heart_beat_interval=30
# Storage 数据和日志目录地址(根目录必须存在,子目录会自动生成)
base_path=/home/data/fastdfs/storage
# 存放文件时 storage server 支持多个路径。这里配置存放文件的基路径数目,通常只配一个目录。
store_path_count=1
# 逐一配置 store_path_count 个路径,索引号基于 0。
## 如果不配置 store_path0,那它就和 base_path 对应的路径一样。
store_path0=/home/data/fastdfs/storage
# FastDFS 存储文件时,采用了两级目录。这里配置存放文件的目录个数。 
## 如果本参数只为 N(如:256),那么 storage server 在初次运行时,会在 store_path 下自动创建 N * N 个存放文件的子目录。
subdir_count_per_path=256
# tracker_server 的列表 ,会主动连接 tracker_server
# 有多个 tracker server 时,每个 tracker server 写一行 公网访问需要配置公网IP
tracker_server=118.31.167.168:22122
# 允许系统同步的时间段 (默认是全天) 。一般用于避免高峰同步产生一些问题而设定。
sync_start_time=00:00
sync_end_time=23:59

创建 storage 基础数据目录,即 base_path 对应的目录

mkdir -p /home/data/fastdfs/storage

使用 ln -s 建立软链接

ln -s /usr/bin/fdfs_storaged /usr/local/bin

storage 服务管理

# 启动、停止、重启
service fdfs_storaged start
service fdfs_storaged stop
service fdfs_storaged restart

# 查看启动监听
netstat -unltp|grep fdfs

注意:启动 storage 前确保 tracker 是启动的。初次启动成功,会在 /home/data/fastdfs/storage 目录下创建 data、logs 两个目录。 如果看到 23000 端口正常被监听后,这时候说明 storage 服务启动成功!

查看 storage 和 tracker 是否在通信

/usr/bin/fdfs_monitor /etc/fdfs/storage.conf

1.1.3.fastDFS服务自测

1、修改 tracker 服务器中的客户端配置文件:

# 复制客户端示例配置文件并重名
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
vim /etc/fdfs/client.conf ## 注需要安装vim命令,没有使用vi命令

编辑 client.conf:

# Client 的数据和日志目录
base_path=/home/data/fastdfs/client

# tracker服务访问地址
tracker_server=118.31.167.168:22122

# 其他参数默认

创建 client 基础数据目录,即 base_path 对应的目录

mkdir -p /home/data/fastdfs/client

2、本地上传文件测试

在 linux 内部执行如下命令上传 name.jpeg 图片(记住需要在name.jpeg文件所在目录):

cd /usr/apps/fast_dfs # 例如这个图片文件在fast_dfs目录下
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf namei.jpeg

上传成功后会返回文件ID号:

# /usr/bin/fdfs_upload_file /etc/fdfs/client.conf name.jpeg 
group1/M00/00/00/rBrXSGNlu5iASIQhAEW1FdaZj-0961.jpg

从返回的文件ID分析结构组成,返回的文件 ID 由 group 、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。

3、防火墙配置

# 添加开放端口
firewall-cmd --zone=public --add-port=22122/tcp --permanent
firewall-cmd --zone=public --add-port=23000/tcp --permanent

# 重启服务加载配置
firewall-cmd --reload
## 查看开放端口
firewall-cmd --list-ports

1.1.4.在nginx中集成fastdfs-nginx-module

1、下载安装 nginx 和 fastdfs-nginx-module 集成安装的依赖库:

yum install readline-devel pcre-devel openssl-devel -y

2、解压 fastdfs-nginx-module-1.20.tar.gz

cd /usr/apps/fast_dfs
tar -xvf fastdfs-nginx-module-1.20.tar.gz

3、进入 fastdfs-nginx-module-1.20 目录,编辑修改 src/config 文件:

vim fastdfs-nginx-module-1.20/src/config

# 修改添加以下内容
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"

4、配置 nginx 安装,加入 fastdfs-nginx-module 模块 (此时就用到了前面提到的 nginx 安装)

cd /usr/apps/nginx/nginx-1.15.1 # 注意nginx源码目录位置
./configure --add-module=/usr/apps/fast_dfs/fastdfs-nginx-module-1.20/src

5、编译、安装

make && make install

关于启动报错 “%PRIx64, get_current_time_us());” 的解决方案:

# 清理 nginx 源码目录的执行 ./configure 指令的文件
make clean
# 解压 fastdfs-nginx-module 备份,然后重命名 fastdfs-nginx-module-test
cd /usr/apps/fast_dfs
unzip 5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip
mv fastdfs-nginx-module-5e5f3566bbfa57418b5506aaefbe107a42c9fcb1 fastdfs-nginx-module-test

# 配置 fastdfs-nginx-module-test/config 后,在 nginx安装,添加 fastdfs-nginx-module-test
cd /usr/apps/fast_dfs/fastdfs-nginx-module-test
vim src/config
## 修改添加以下内容
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
## 报存好后执行nginx安装配置加载模块,再次执行编译和安装
./configure --add-module=/usr/apps/fast_dfs/fastdfs-nginx-module-test/src
make && make install

6、查看安装结果:

/usr/local/nginx/sbin/nginx -v

# 正常情况下安装完成后执行命令会提示两行信息(1行nginx版本信息,1行nginx加载的其他模块信息)
# 安装 fastdfs-nginx-module-test 成功的,只有一行 nginx信息-- 这是正常的

7、配置 fastdfs-nginx-module 设置

复制 fastdfs-nginx-module-*(1.20/test) 源码中的配置文件到 /etc/fdfs 目录并修改:

cp /usr/apps/fast_dfs/fastdfs-nginx-module-test/src/mod_fastdfs.conf /etc/fdfs/
vim /etc/fdfs/mod_fastdfs.conf
# 连接超时时间
connect_timeout=10
# Tracker Server
tracker_server=118.31.167.168:22122
# StorageServer 默认端口
storage_server_port=23000
# 如果文件ID的uri中包含/group**,则要设置为true  ##这里不改的话,按照完整资源请求时nginx会报400错误
url_have_group_name=true
# Storage 配置的store_path0路径,必须和storage.conf中的一致
store_path0=/home/data/fastdfs/storage

8、复制 FastDFS 的部分配置文件到 /etc/fdfs 目录

cp /usr/apps/fast_dfs/fastdfs-5.05/conf/http.conf /etc/fdfs/
cp /usr/apps/fast_dfs/fastdfs-5.05/conf/mime.types /etc/fdfs/

9、配置 nginx 代理设置,修改 nginx.conf:

location ~/group([0-9])/M00 {
    ngx_fastdfs_module;
}

10、启动Nginx:

/usr/local/nginx/sbin/nginx
ngx_http_fastdfs_set pid=22440
# 看到 ngx_http_fastdfs_set 表示确实集成 fastdfs-nginx-module 成功。

11、测试验证,浏览器访问前面上传成功的文件,路径例如:http://118.31.167.168/group1/M00/00/00/rBrXSGNlu5iASIQhAEW1FdaZj-0961.jpg

1.2.使用 Java 连接 fastDFS 服务

1.首先创建一个 springboot 工程,取名为:fastdfs-example。

pom依赖内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.raos.fastdfs</groupId>
    <artifactId>fastdfs-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>net.oschina.zcx7878</groupId>
            <artifactId>fastdfs-client-java</artifactId>
            <version>1.27.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.配置 FastDFS 客户端配置 fdfs_client.conf 设置

connect_timeout = 60
network_timeout = 60
charset = UTF-8
http.tracker_http_port = 80
tracker_server = 118.31.167.168:22122

connect_timeout:连接超时时间,单位为秒。
network_timeout:通信超时时间,单位为秒。发送或接收数据时。假设在超时时间后还不能发送或接收数据,则本次网络通信失败
charset: 字符集
http.tracker_http_port:tracker的http端口 (/etc/fdfs/tracker.conf中对应那个)
tracker_server: tracker服务器IP和端口设置

3.配置 application.yml

server:
  port: 8090
spring:
  servlet:
    multipart:
      max-file-size: 10MB    #单文件大小
      max-request-size: 10MB #设置总上传的数据大小
  application:
    name: fast-dfs—java

file:
  url: 118.31.167.168:80

4.创建 FastDFS 文件属性封装类

@AllArgsConstructor // 全有参构造
@NoArgsConstructor // 无参构造
@Data
public class FastDfsFile implements Serializable {

    //文件名字
    private String name;

    //文件内容
    private byte[] content;

    //文件扩展名
    private String ext;

    //文件MD5摘要值
    private String md5;

    //文件创建作者
    private String author;

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

}

5.编写 FastDFS 客户端工具类

public class FastDFSClient {

    /**
     * 初始化tracker信息
     */
    static {
        try {
            // 获取tracker的配置文件fdfs_client.conf的位置
            String filePath = new ClassPathResource("fdfs_client.conf").getPath();
            // 加载tracker配置信息
            ClientGlobal.init(filePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件上传
     *
     * @param file : 要上传的文件信息封装->FastDFSFile
     * @return String[] 1:文件上传所存储的组名 2:文件存储路径
     */
    public static String[] upload(FastDfsFile file) {
        //获取文件作者
        NameValuePair[] metaList = new NameValuePair[1];
        metaList[0] = new NameValuePair(file.getAuthor());

        /**
         * 文件上传后的返回值
         * uploadResults[0]:文件上传所存储的组名,例如:group1
         * uploadResults[1]:文件存储路径,例如:M00/00/00/wKjThF0DBzaAP23MAAXz2mMp9oM26.jpeg
         */
        String[] uploadResults = null;
        try {
            //创建TrackerClient客户端对象
            TrackerClient trackerClient = new TrackerClient();
            //通过TrackerClient对象获取TrackerServer信息
            TrackerServer trackerServer = trackerClient.getConnection();
            //获取StorageClient对象
            StorageClient storageClient = new StorageClient(trackerServer, null);
            //执行文件上传
            uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), metaList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return uploadResults;
    }

    /**
     * 下载图片
     *
     * @param groupName      文件存储组名
     * @param remoteFileName 文件名称
     * @return
     * @throws Exception
     */
    public static byte[] downFile(String groupName, String remoteFileName) throws Exception {
        //1.创建一个配置文件 用于填写服务端的ip和端口
        //2.加载配置文件 建立链接
        //3.创建trackerClient
        TrackerClient trackerClient = new TrackerClient();
        //4.根据trackerclient获取到链接对象 trackerServer
        TrackerServer trackerServer = trackerClient.getConnection();
        //5.创建storageServer对象 设置null

        //6.创建stroageClient --->提供了很多的操作图片的API的代码(上传图片,下载 ,删除)
        StorageClient storageClient = new StorageClient(trackerServer, null);

        //7.下在图片
        //参数1 指定要下载的组名
        //参数2 指定要下载的远程文件路径
        return storageClient.download_file(groupName, remoteFileName);
    }

    /**
     * 获取文件信息
     *
     * @param groupName      组名
     * @param remoteFileName 文件存储完整名
     */
    public static FileInfo getFile(String groupName, String remoteFileName) {
        try {
            //创建TrackerClient对象
            TrackerClient trackerClient = new TrackerClient();
            //通过TrackerClient获得TrackerServer信息
            TrackerServer trackerServer = trackerClient.getConnection();
            //通过TrackerServer获取StorageClient对象
            StorageClient storageClient = new StorageClient(trackerServer, null);
            //获取文件信息
            return storageClient.get_file_info(groupName, remoteFileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 删除图片
     *
     * @param groupName      组名
     * @param remoteFileName 文件存储完整名
     * @return
     * @throws Exception
     */
    public static boolean deleteFile(String groupName, String remoteFileName) throws Exception {
        //1.创建一个配置文件 用于填写服务端的ip和端口
        //2.加载配置文件 建立链接
        //3.创建trackerClient
        TrackerClient trackerClient = new TrackerClient();
        //4.根据trackerclient获取到链接对象 trackerServer
        TrackerServer trackerServer = trackerClient.getConnection();
        //5.创建storageServer对象 设置null

        //6.创建stroageClient --->提供了很多的操作图片的API的代码(上传图片,下载 ,删除)
        StorageClient storageClient = new StorageClient(trackerServer, null);
        int group1 = storageClient.delete_file(groupName, remoteFileName);

        return group1 == 0;
    }

}

6.编写测试Controller

@Slf4j
@RequestMapping("/fileManage")
@RestController
public class FileController {

    @Value("${file.url}")
    private String fileUrl;

    @PostMapping("/upload")
    public String upload(MultipartFile file) {
        try {
            if (!file.isEmpty()) {
                //1.获取到文件本身的字节数组
                byte[] content = file.getBytes();
                //2.获取文件的名称 --> 获取图片的后缀
                String name = file.getOriginalFilename();
                //3.上传到fastdfs上
                //[0] =group1
                //[1] =M00/00/00/wKjThF-qeNyATiVHAAAl8vdCW2Y824.png
                String[] upload = FastDFSClient.upload(new FastDfsFile(
                        name,
                        content,
                        StringUtils.getFilenameExtension(name)
                ));
                //4.拼接Ulr
                // http://118.31.167.168:80/group1/M00/00/00/wKjThF-qeNyATiVHAAAl8vdCW2Y824.png
                String realPath = fileUrl + "/" + upload[0] + "/" + upload[1];
                log.info("上传文件的访问url=[{}]", realPath);
                //5.返回url给页面
                return realPath;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

}

7.postman 上传文件,路径:http://localhost:8090/fileManage/upload,方式:POST,选择 form-data,key为:file,value类型文件文件,选择文件。
成功后会返回url路径,例如:http://118.31.167.168:80/group1/M00/00/00/wKjThF-qeNyATiVHAAAl8vdCW2Y824.png,通过浏览器可以看到图片表示OK。

若对上述安装 FastDFS 的步骤感觉繁琐,请移步 FastDFS安装笔记,这篇文章已经顺利采坑。

 类似资料: