分布式文件存储FastDFS 服务的搭建和代码实现

5 篇文章 0 订阅
4 篇文章 0 订阅

分布式文件存储FastDFS

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

FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

FastDFS 架构包括 Tracker serverStorage server。客户端请求 Tracker server 进行文件上传、下载,通过Tracker server 调度最终由 Storage server 完成文件上传和下载。

Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器。Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上,Storageserver 没有实现自己的文件系统而是利用操作系统的文件系统来管理文件。可以将storage称为存储服务器。

大白话

FastDFS 两个组件
1.Tracker 负责文件管理的负载均衡操作,控制中心(注册中心)
2.Storage 干活的(文件的上传、下载等操作)
3.FastDFS 没有主从的的概念。只有同步多个组合在一起就是集群

工作流程

在这里插入图片描述

上传流程

在这里插入图片描述

上传返回格式如下

group1/M00/02/44/1.png

备注说明

1.客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。
2.组名:文件上传后所在的storage组名称,在文件上传成功后有storage 服务器返回,需要客户端自行保存。
3.虚拟磁盘路径:storage 配置的虚拟路径,与磁盘选项store_path*对应。如果配置了
store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推。
4.数据两级目录:storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。
5.文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器 IP 地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息

服务器操作

1.安装fastdfs,本人是基于docker容易来操作的

1.1获取镜像

docker pull morunchang/fastdfs

1.2 运行Tracker

docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh

1.3运行storage

docker run -d --name storage --net=host -e TRACKER_IP=192.168.1.1:22122 -e GROUP_NAME=group1 morunchang/fastdfs sh storage.sh
使用的网络模式是–net=host, 192.168.1.1是宿主机的IP
group1是组名,即storage的组
如果想要增加新的storage服务器,再次运行该命令,注意更换 新组名

1.4 设置容器开机自启动

docker update --restart=always tracker
docker update --restart=always storage

2. Nginx 配置

Nginx 主要提供对FastDFS文件访问的支持,需要添加Nginx_FastDFS_Module

访问图片 用户访问时通过nginx访问,ngnix会找到这个模块对应的storage组

2.1 修改nginx配置文件
vim /etv/nginx/conf/nginx.conf
在server中添加如下内容

 location ~ /M00 {
                root /data/fast_data/data;
                ngx_fastdfs_module;
 }

代码操作

语言不限,php/java都是相同的,这为了操作就采用java来开发啦

1.构建项目就不用多解释了,用的是spring boot快速的构建一个
构建完成后
在pom.xml中添加fastdfs的依赖

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

2.添加fdfs_client.conf配置文件在resource目录下

# 链接超时时间
connect_timeout=60
#网络请求超时时间
network_timeout=60
charset=UTF-8
# tracker http端口
http.tracker_http_port=8080
# tracker TCP通信端口  安装服务时的端口号
tracker_server=10.211.55.4:22122
项目代码

在这里插入图片描述

  1. 控制器controller类
  2. 工具类上传
  3. 文件信息封装类

controller

package com.demo.fast.controller;

import com.demo.fast.file.FastDFSFile;
import com.demo.fast.utils.FastDFSUtil;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Author cxk
 * @date 2020/10/5 01:05
 */
@RestController
@RequestMapping("/upload")
@CrossOrigin
public class FileController {

    @PostMapping
    public String upload(@RequestParam(value = "file")MultipartFile multipartFile) throws Exception{
        //封装文件信息
        FastDFSFile fastDFSFile = new FastDFSFile(
                multipartFile.getOriginalFilename(), //文件名字 1.png
                multipartFile.getBytes(),  //文件字节数组
                StringUtils.getFilenameExtension(multipartFile.getOriginalFilename()) //获取文件扩展名
        );
        //调用封装好的工具类将文件传入进去就可以
        String[] upload = FastDFSUtil.upload(fastDFSFile);
        //拼接访问地址 nginx 访问地址
        // url = http://10.211.55.4:8080/upload[0]/upload[1]
        String url = "http://10.211.55.4:8080/" + upload[0] + "/" + upload[1];
        //在这你就可以吧url存入到你的数据库中去啦
        return url;
    }
}

工具类 FastDFSUtil

package com.demo.fast.utils;

import com.demo.fast.file.FastDFSFile;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;

/**
 * @Author cxk
 * @date 2020/10/5 01:06
 * 工具类
 */
public class FastDFSUtil {

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


    public static String[]  upload(FastDFSFile fastDFSFile) throws Exception{
        // 创建Tracker 访问客户端对象的创建TrackerClient
        TrackerClient trackerClient = new TrackerClient();
        // 通过TrackerClien 访问TrackerServer 服务 获取连接信息
        TrackerServer trackerServer = trackerClient.getConnection();
        //通过TrackerServer连接信息客户已获取Storage信息,创建StorageClient对象c存储StorageClient 信息
        StorageClient storageClient = new StorageClient(trackerServer, null);
        //通过StorageClient 访问Storage 实现文件上传并且获取文件存储后的信息
        /**
         * 参数1  上传文件的字节数字
         * 参数2 文件上传的扩展名
         * 参数3  附加参数
         */
//        NameValuePair[] meta_list = new NameValuePair[1];
//        meta_list[0] = new NameValuePair("author",fastDFSFile.getAuthor());
//        storageClient.upload_file(fastDFSFile.getContent(),fastDFSFile.getExt(),meta_list);
        //附加参数 获取作者
        /**
         * 返回的参数说明
         *  file[0]  返回文件存储在storage的组的名字  group1
         *  file[1]  返回文件存储在storage上的文件民资  M00/02/44/1.png
         */

        String[] file = storageClient.upload_file(fastDFSFile.getContent(), fastDFSFile.getExt(), null);
        return file;
    }
}

文件信息封装 FastDFSFile

package com.demo.fast.file;

import java.io.Serializable;

/**
 * @Author cxk
 * @date 2020/10/5 01:07
 *  封装文件上传等信息
 */
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;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public byte[] getContent() {
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

    public String getExt() {
        return ext;
    }

    public void setExt(String ext) {
        this.ext = ext;
    }

    public String getMd5() {
        return md5;
    }

    public void setMd5(String md5) {
        this.md5 = md5;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}

启动项目

postman测试访问
127.0.0.1:10086/upload

如下图返回连接地址在存入到数据库当中就OK了
在这里插入图片描述
访问

http://10.211.55.4:8080/group1/M00/00/00/CtM3BF96Ea6AdHhSAAI_WH8DBGE491.png

写了一个完整的demo有需要的小伙伴可以去下载下来看看
demo地址

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值