FastDFS实战笔记

分布式文件系统FastDFS 实战笔记之单点部署

1、FastDFS简介

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。

FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。它是由阿里巴巴开发,c语言实现的简单、高效、灵活的分布式文件系统。

分布式文件系统:传统的文件存储系统是存放在单台服务器上,如果服务器出现问题就会导致用户不能进行文件的上传和下载。而分布式文件系统采用多台服务器来存放数据,中间添加一个分布式文件管理来协调文件上传和下载。在分布式文件系统中,如果某个单个节点出现故障,还有其他节点可以继续进行文件的上传和下载。并且分布式文件系统有数据备份的功能可以防止数据的丢失,也可以提供扩容机制,无限增加存储的大小。

image-20220225111458070

2、FastDFS 安装

实战部分全部是在centos7的系统下进行!!!

前期准备:
需要准备gcclibeventlibevent-devel等环境。

yum install gcc libevent libevent-devel -y  # 安装命令

开始安装:

  1. 安装libfastcommon公共函数库。
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz # 在/etc/soft下使用命令
tar -zxvf V1.0.7.tar.gz # 解压
./make.sh # 进入到libfastcommon-1.0.7目录下编译
./make.sh install # 安装
  1. 安装FastDFS
wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz # 在/etc/soft下使用命令
tar -zxvf V5.05.tar.gz # 解压
./make.sh # 编译
./make.sh install # 安装
  1. 检查是否安装成功,在/usr/bin这个目录下是否存在以fast-开头的若干文件,这些文件是fastdfs的启动命令。

image-20220225124741816

  1. fastdfs的配置文件,在/etc/soft/fastdfs-5.05/conf/目录下,需要将这个目录下的http.confmime.type拷贝到/etc/fdfs/这个目录下。
cp http.conf /etc/fdfs/
cp mime.types /etc/fdfs/

3、FastDFS 配置和启动

  1. tracker.conf.sample配置:
# the tracker server port
# tracker的端口号,默认就行不用改,但是需要记住
port=22122
# the base path to store data and log files
# 会在这个目录下生成一些日志文件,这个目录需要自己手动创建
base_path=/home/xiaotanke/fastdfs/tracker
  1. storage.conf.sample配置:
# the base path to store data and log files
# 日志文件的存放位置,自己手动创建
base_path=/home/xiaotanke/fastdfs/storage
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
# 上传文件的保存路径,这个目录必须存在,并且是手动创建的
store_path0=/home/xiaotanke/fastdfs/storage/files
#store_path1=/home/yuqing/fastdfs2
# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
# 主机的ip地址,需要与自己的服务器对应,如果只需要在内网访问,就只需要配置内网就可以,如果需要外网访问就需要配置外网,一般都是配置内网,因为代码是在服务器上跑,这样更加安全
# 如果需要使用外网访问,需要把防火墙的22122端口打开
tracker_server=xx.xx.xx.xx:22122
  1. 启动
# 启动tracker
fdfs_trackerd /etc/fdfs/tracker.conf

# 启动stroage
fdfs_storaged /etc/fdfs/storage.conf

# 启动完成后查看进程是否启动成功
ps -ef|grep fdfs

image-20220322084535377

像这样就是启动成功了,进入之前配置的文件保存路径 /home/xiaotanke/fastdfs/storage/files/data,会生成下面这些文件夹,这样就启动成功了。

image-20220322084757199

  1. 关闭和重启服务
# 操作 tracker
fdfs_trackerd /etc/fdfs/tracker_conf stop/restart # 停止和重启服务
# 操作 stroage
fdfs_storaged /etc/fdfs/storage_conf stop/restart # 停止和重启服务

kill -9 服务名称 # 也可以通过这个方式来强制停止服务,这样存在一定危险,不建议使用

4、测试文件上传、下载、删除

测试上传

进入 /etc/fdfs 下,会发现有一个 client.conf.sample,将文件修改为 client.conf,并进行下面的配置,这个配置文件只用于测试,没有其他作用。

# 配置日志文件,这个文件夹需要手动创建
base_path=/home/xiaotanke/fastdfs/client

#  配置访问地址,需要开启防火墙22122端口
tracker_server=xx.xx.xx.xx:22122
# 测试
# Usage: fdfs_test <配置文件client> <操作,upload/download/delete>
#	operation: upload, download, getmeta, setmeta, delete and query_servers

# 上传测试,还需要开启防火墙的23000端口
fdfs_test /etc/fdfs/client.conf upload test.txt 
[root@xiaotanke ~]# fdfs_test /etc/fdfs/client.conf upload test.txt 

# 下面是上传成功的输出
[2022-03-22 09:42:39] DEBUG - base_path=/home/xiaotanke/fastdfs/client, connect_timeout=30, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0

tracker_query_storage_store_list_without_group: 
	server 1. group_name=, ip_addr=xx.xx.xx.xx, port=23000

# group_name 是配置的组名,决定文件存放在哪个主机上
# remote_filename 是远程文件名 M00 是磁盘路径,是在storage.conf中配置的,M00是第一个磁盘路径,表示就是/home/xiaotanke/fastdfs/storage/files,rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt就是上传的文件名
# storage.conf中的配置
    # store_path_count=1,磁盘数目,默认是1,可以配置多个保存文件磁盘
    # store_path0=/home/xiaotanke/fastdfs/storage/files  磁盘路径
group_name=group1, ip_addr=xx.xx.xx.xx, port=23000
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt
source ip address: xx.xx.xx.xx
file timestamp=2022-03-22 09:42:39
file size=36
file crc32=2057575212
# url是远程访问路径,但是不能访问,需要配置nginx才能访问
example file url: http://xx.xx.xx.xx/group1/M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt
storage_upload_slave_by_filename

进入/home/xiaotanke/fastdfs/storage/files/00/00,就会发现rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt这个文件,这就上传成功了。

image-20220322102258076

image-20220322102542793

测试下载

fdfs_test /etc/fdfs/client.conf group1 M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt
# group1是组名 
# M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt 是文件的磁盘访问路径

测试删除

fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435_big.txt
# 与下载类似

5、配置NginxFastDFS的 HTTP 访问

安装nginx

wget http://nginx.org/download/nginx-1.10.3.tar.gz # 安装命令
tar -zxvf nginx-1.10.3.tar.gz # 解压

安装fastDFS-Nginx-module这个扩展模块

wget http://jaist.dl.sourceforge.net/project/fastdfs/FastDFS%20Nginx%20Module%20Source%20Code/fastdfs-nginx-module_v1.16.tar.gz	# 下载扩展模块
tar -zxvf fastdfs-nginx-module_v1.16.tar.gz	# 解压

配置nginx

# 进入到解压后的fastdfs-nginx-module的src目录下,并记录下这个src的目录位置 /etc/soft/fastdfs-nginx-module/src
# 然后进入自己的nginx目录,使用下面这个命令
./configure --prefix=/usr/local/nginx_fdfs --add-module=/etc/soft/fastdfs-nginx-module/src
# /usr/local/nginx_fdfs是扩展模块存放的位置
make # 编译
# 如果在make时出现 fatal error: fdfs_define.h: No such file or directory这个错误
# 需要修改fastdfs-nginx-module-1.20/src/config文件,在从1处重新配置
# ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
# CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
make install # 安装

安装完成后,可以在 /usr/local这个目录下看见 nginx-fdfs,这样就安装成功了。

image-20220322160747811

配置Nginx-fdfs

# 扩展包的配置,将扩展包下的src下的 mod_fastdfs.conf 拷贝到 /etc/fdf目录下
mv mod_fastdfs.conf /etc/fdfs
# 然后进行下面的配置
# 配置tracker的地址
tracker_server=xx.xx.xx.xx:22122
# 默认是false,需要改为true
url_have_group_name = true
# 磁盘数目,必须和storage.conf中的磁盘数目一样
store_path_count=1
# 文件存储位置
store_path0=/home/xiaotanke/fastdfs/storage/files


# 配置nginx_fdfs,配置nginx_fdfs中的conf目录中,编辑nginx.conf这个文件
 server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

		# 就增加这一个配置就可以了
        location ~ /group[1-9]/M0[0-9]{
                ngx_fastdfs_module;
        } 
	。。。
}

启动nginx-fdfs

/usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf -t # 测试配置文件
/usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf # 启动服务器
ps -ef | grep nginx # 查看nginx的服务进程

image-20220322191140015

== 如果出现错误,就查看 nginx_fdfs这个目录下的日志文件,进行错误的检查。==

测试

如果前面的配置都没有问题,就可以通过之前上传文件 fastdfs 返回的 url进行 http 访问。http://xx.xx.xx.xx/group1/M00/00/00/rBE6PmI5vGeAfz4zAABsPFBxCKc33.docx,下面就是在下载文件。

image-20220322201344416

6、FastDFS 扩展模块执行流程

image-20220326155158916

## 7、java实现文件上传、下载、删除

导入依赖

由于在maven中央仓库中没有fastdfs的依赖,我们使用别人的替代依赖。

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

编写配置文件:在resources目录下创建fdfs_client.conf文件

connect_timeout = 2
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 9001
# http.anti_steal_token = no
# http.secret_key = FastDFS1234567890
# tracker的ip地址和端口号
tracker_server = xx.xx.xx.xx:222122

connection_pool.enabled = true
connection_pool.max_count_per_entry = 500
connection_pool.max_idle_time = 3600
connection_pool.max_wait_time_in_ms = 1000

文件上传

package com.xiaotanke;

import org.csource.common.MyException;
import org.csource.fastdfs.*;
import java.io.IOException;

/**
 * @author tanKe
 * Date on 2022/3/26  16:01
 */
public class FastDFSUtil {
    private static TrackerClient trackerClient = null;
    private static TrackerServer trackerServer = null;
    private static StorageClient storageClient = null;
    private static StorageServer storageServer = null;

    // 初始化
    static {
        // 将配置文件的tracker地址读取到内存中
        try {
            ClientGlobal.init("fdfs_client.conf");
            trackerClient = new TrackerClient();
            trackerServer = trackerClient.getConnection();
            storageServer = trackerClient.getStoreStorage(trackerServer);
            storageClient = new StorageClient(trackerServer,storageServer);
        } catch (IOException | MyException e) {
            e.printStackTrace();
        }
    }

    /**
     * FastDFS 文件上传测试
     */
    public static void upload() throws MyException, IOException {
        // 本地文件上传方法
        // 参数1:文件路径;参数2:文件扩建名;参数3:文件属性,通常不上传
        // 路径必须是一个绝对路径
        String[] result = storageClient.upload_file("e:/favicon.png", "png", null);
        // 返回值是一个数组,一个存在两个值
        // 第一个值是上传后的组名
        // 第二个值是上传后的文件存储路径
        System.out.println(result[0]);
        System.out.println(result[1]);
    }
}

image-20220326164831911

文件下载:前面初始化内容不变

/**
 * 文件下载测试
 * @param groupName 文件组名
 * @param filePath 文件存储路径
 * @param fileName 文件保存名称
 */
public static Integer download(String groupName,String filePath,String fileName) throws MyException, IOException {
    // 返回结果是0表示下载成功,如果不是0而是其它值就表示下载失败
    return storageClient.download_file(groupName, filePath, fileName);
}
try {
    Integer result = FastDFSUtil.download("group1", "M00/00/00/rBE6PmI-196AbE6BAAAWUYjKqeY490.png", "test.png");
    if (result==0){
        System.out.println("文件下载成功");
    }else{
        System.out.println("文件下载失败");
    }
} catch (MyException | IOException e) {
    e.printStackTrace();
}

image-20220326172601971

文件删除:初始化不变

/**
 * 删除文件测试
 * @param groupName 组名
 * @param filePath 文件存储路径
 */
public static Integer delete(String groupName,String filePath) throws MyException, IOException {
    // 返回值为0则表示删除成功,返回值为1表示删除失败
    return storageClient.delete_file(groupName,filePath);
}
try {
    Integer result = FastDFSUtil.delete("group1", "M00/00/00/rBE6PmI-0wCAIJTEAAAWUYjKqeY103.png");
    if (result==0){
        System.out.println("文件删除成功");
    }else{
        System.out.println("文件删除失败");
    }
} catch (MyException | IOException e) {
    e.printStackTrace();
}

8、java-web实现FastDFS文件上传

导入依赖

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

编写配置文件

编写工具类

package com.xiaotanke.util;

import org.csource.common.MyException;
import org.csource.fastdfs.*;
import java.io.IOException;

/**
 * @author tanKe
 * Date on 2022/3/26  16:01
 */
public class FastDFSUtil {
    private static StorageClient storageClient = null;


    // 初始化
    static {
        // 将配置文件的tracker地址读取到内存中
        try {
            ClientGlobal.init("fdfs_client.conf");
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            storageClient = new StorageClient(trackerServer, storageServer);
        } catch (IOException | MyException e) {
            e.printStackTrace();
        }
    }

    /**
     * FastDFS 文件上传测试
     */
    public static String[] upload(byte[] fileByte,String fileExtendName) throws MyException, IOException {
        // 本地文件上传方法
        // 参数1:文件字节数组;参数2:文件扩建名;参数3:文件属性,通常不上传
        // web上传文件通常是通过字节的方式来上传
        return storageClient.upload_file(fileByte,fileExtendName,null);
        // 返回值是一个数组,一个存在两个值
        // 第一个值是上传后的组名
        // 第二个值是上传后的文件存储路径
    }

    /**
     * 文件下载测试
     * @param groupName 文件组名
     * @param filePath 文件存储路径
     * @param fileName 文件保存名称
     */
    public static Integer download(String groupName,String filePath,String fileName) throws MyException, IOException {
        // 返回结果是0表示下载成功,如果不是0而是其它值就表示下载失败
        return storageClient.download_file(groupName, filePath, fileName);
    }

    /**
     * 删除文件测试
     * @param groupName 组名
     * @param filePath 文件存储路径
     */
    public static Integer delete(String groupName,String filePath) throws MyException, IOException {
        // 返回值为0则表示删除成功,返回值为1表示删除失败
        return storageClient.delete_file(groupName,filePath);
    }
}

编写控制器

package com.xiaotanke.controller;

import com.xiaotanke.util.FastDFSUtil;
import org.csource.common.MyException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * @author tanKe
 * Date on 2022/3/26  19:28
 */
@Controller
public class FastDFSWeb {

    @PostMapping("/upload")
    public String upload(@RequestParam("myFile") MultipartFile multipartFile){
        if (multipartFile==null){
            return "fail";
        }
        String fileName = multipartFile.getOriginalFilename();
        System.out.println(fileName);
        if (ObjectUtils.isEmpty(fileName)){
            return "fail";
        }
        int index = fileName.lastIndexOf(".");
        String type = fileName.substring(index);
        String[] result = null;
        try {
            result = FastDFSUtil.upload(multipartFile.getBytes(), type);
        } catch (MyException | IOException e) {
            e.printStackTrace();
            return "fail";
        }
        if (result==null){
            return "fail";
        }
        return "success";
    }
}

前端页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>测试页面</title>
</head>
<body>
<form action="http://127.0.0.1:8080/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="myFile"/>
  <input type="submit" value="上传文件">
</form>
</body>
</html>
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值