分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

之前大学时搭建过一个FastDFS的图片服务器,当时只是抱着好奇的态度搭着玩一下,当时搭建采用了一台虚拟机,tracker和storage服务在一台机器上放着,最近翻之前的博客突然想着在两台机器上搭建试一下,顺便整合了SpringBoot实现了一下图片的上传服务。

新的阅读体验地址: 嘿嘿

一、传统文件上传问题:

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

如果我们现在用户使用的是第一胎服务器Tomcat1上传了文件,然后当用户访问Tomcat1时候可以访问到上传的文件、图片等等,但是如果当用户访问到Tomcat2和Tomcat3的时候,由于文件资源在Tomcat1上面,所以他是访问不到对应的资源的;这时就可以使用到分布式文件系统FastDFS了。

二、什么是分布式文件系统

  • 随着文件数据的越来越多,通过tomcat或nginx虚拟化的静态资源文件在单一的一个服务器节点内是存不下的,如果用多个节点来存储也可以,但是不利于管理和维护,所以我们需要一个系统来管理多台计算机节点上的文件数据,这就是分布式文件系统。
  • 分布式文件系统是一个允许文件通过网络在多台节点上分享的文件系统,多台计算机节点共同组成一个整体,为更多的用户提供分享文件和存储空间。比如常见的网盘,本质就是一个分布式的文件存储系统。虽然我们是一个分布式的文件系统,但是对用户来说是透明的,用户使用的时候,就像是访问本地磁盘一样。
  • 分布式文件系统可以提供冗余备份,所以容错能力很高。 系统中有某些节点宕机,但是整体文件服务不会停止,还是能够为用户提供服务,整体还是运作的,数据也不会丢失。
  • 分布式文件系统的可扩展性强,增加或减少节点都很简单,不会影响线上服务,增加完毕后会发布到线上,加入到集群中为用户提供服务。
  • 分布式文件系统可以提供负载均衡能力,在读取文件副本的时候可以由多个节点共同提供服务,而且可以通过横向扩展来确保性能的提升与负载。

三、为什么要使用分布式文件系统

使用分布式文件系统可以解决如下几点问题:

  1. 海量文件数据存储
  2. 文件数据高可用(冗余备份)
  3. 读写性能和负载均衡

以上3点都是我们之前使用tomcat或nginx所不能够实现的,这也是我们为什么要使用分布式文件系统的原因

四、FastDFS 与 HDFS

说到分布式文件存储,肯定会有人想到HDFS,他们两者主要定位和应用场景是不一样的。

  1. Hadoop中的文件系统HDFS主要解决并行计算中分布式存储数据的问题。其单个数据文件通常很大,采用了分块(切分)存储的方式,所以是大数据大文件存储来使用的场景。
  2. FastDFS主要用于互联网网站,为文件上传和下载提供在线服务。所以在负载均衡、动态扩容等方面都支持得比较好,FastDFS不会对文件进行分快存储。FastDFS用于存储中小文件都是不错的,比如用户头像啊,一些较小的音视频文件啊等等都行。

五、FastDFS常见术语

  1. tracker:追踪者服务器,主要用于协调调度,可以起到负载均衡的作用,记录storage的相关状态信息。
  2. storage:存储服务器,用于保存文件以及文件的元数据信息
  3. group:组,同组节点提供冗余备份,不同组用于扩容
  4. mata data: 文件的元数据信息,比如长宽信息、图片后缀,视频帧数等

六、FastDFS架构

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

tracker和storage是有心跳信息的,需要先启动tracker

七、FasfDFS文件上传过程

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

八、FastDFS下载过程

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

九、FastDFS搭建:

准备:

  • 安装包准备
链接:https://pan.baidu.com/s/1Lic4JfUT4a8YdYmqJ5_vcQ ;
提取码:bm0a
复制这段内容后打开百度网盘手机App,操作更方便哦

两台服务器

  • tracker服务:192.168.2.120 、storage服务:192.168.2.121,如下图:

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传
1、基本环境搭建:
  • 安装基础环境
yum install -y gcc gcc-c++
yum -y install libevent
  • 安装libfastcommon函数库
1.解压
tar -zxvf libfastcommon-1.0.42.tar.gz
2.进入解压后的文件夹编译并安装
cd libfastcommon-1.0.42/
./make.sh
./make.sh install
  • 安装FastDFS主程序文件
1.解压
tar -zxvf fastdfs-6.04.tar.gz
2.进入到fastdfs目录,查看fastdfs安装配置
cd fastdfs-6.04/
vim make.sh
3.安装fastdfs
./make.sh
./make.sh install
4.将FastDFS中conf中的文件拷贝到 /etc/fdfs下
cp /software/FastDFS/fastdfs-6.04/conf/*  /etc/fdfs/
2、配置tracker服务

进入 /etc/fdfs 修改配置文件 tracker.conf

1.修改文件路径
base_path=/usr/local/fastdfs/tracker
2.创建文件路径
mkdir /usr/local/fastdfs/tracker -p
3.启动
/usr/bin/fdfs_trackerd  /etc/fdfs/tracker.conf
4.查看服务
ps -ef|grep tracker
5.停止tracker
/usr/bin/stop.sh /etc/fdfs/tracker.conf
3.配置storage服务

进入 /etc/fdfs 修改配置文件 storage.conf

1.修改配置文件 storage.conf
修改组名
group_name=zhouhong
修改storage的工作空间
base_path=/usr/local/fastdfs/storage
修改storage的存储空间
store_path0=/usr/local/fastdfs/storage
修改tracker的地址和端口号,用于心跳
tracker_server=192.168.2.120:22122
后续结合nginx的一个对外服务端口号
http.server_port=8888
2.创建目录
mkdir /usr/local/fastdfs/storage -p
3.启动
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
4.查看
ps -ef|grep storage
4、测试

修改 /etc/fdfs 下 client.conf文件

1.修改client.conf文件
  base_path=/usr/local/fastdfs/client
  tracker_server=192.168.2.120:22122
2.创建目录
mkdir /usr/local/fastdfs/client
3.准备一张图片测试
/usr/bin/fdfs_test /etc/fdfs/client.conf  upload  zhouhong.jpg

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

成功!

5、配置 nginx fastdfs 实现文件服务器

Nginx需要跟storage安装在同一台服务器上面

fastdfs安装好以后是无法通过http访问的,这个时候就需要借助nginx了,所以需要安装fastdfs的第三方模块到nginx中,就能使用了。

  • 安装nginx插件
1.解压
tar -zxvf fastdfs-nginx-module-1.22.tar.gz
2.复制配置文件
cp /software/FastDFS/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf  /etc/fdfs/
3.修改/fastdfs-nginx-module/src/config文件
修改/fastdfs-nginx-module/src/config文件,主要是修改路径,把local删除,
因为fastdfs安装的时候我们没有修改路径,原路径是/usr

如图所示,将local删除即可

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传
  • 安装Nginx
1.环境安装
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y gcc-c++
yum install -y openssl openssl-decel
2.解压
tar -zxvf nginx-1.16.1.tar.gz
3.创建目录
mkdir /var/temp/nginx -p
4.进入解压目录、最后一个为fastdfs-nginx-module-1.22解压目录
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--add-module=/software/FastDFS/fastdfs-nginx-module-1.22/src
5.安装
make
make install
6.修改 /etc/fdfs/mod_fastdfs.conf
base_path=/usr/local/fastdfs/tmp
tracker_server=192.168.2.120:22122
group_name=zhouhong
url_have_group_name = true
store_path0=/usr/local/fastdfs/storage
7.创建目录
mkdir /usr/local/fastdfs/tmp
8.修改/usr/local/nginx/conf/nginx.conf
server {
        listen       8888;
        server_name  localhost;
        location /zhouhong/M00 {
            ngx_fastdfs_module;
        }
    }

找到刚才上传的图片

cd  /usr/local/fastdfs/storage/data/00/00
ls

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

十、FastDFS与SpringBoot整合实现文件上传

1、引入依赖
com.github.tobato
        fastdfs-client
        1.26.7
2、配置文件
############################################################
#
fdfs 配置
#
############################################################
fdfs:
  connect-timeout: 30   # 连接的超时时间
  so-timeout: 30        # 读取的超时时间
  tracker-list: 192.168.2.120:22122   # tracker服务所在的ip地址和端口号
3、FileService主要逻辑代码
@Autowired
    private FastFileStorageClient fastFileStorageClient;
    @Override
    public String upload(MultipartFile file, String fileExtName) throws Exception {
        StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(),
                                file.getSize(),
                                fileExtName,
                                null);
        String path = storePath.getFullPath();
        return path;
    }
4、FileController主要逻辑代码
@RestController
@RequestMapping("fdfs")
public class CenterUserController  {
    @Autowired
    private FileResource fileResource;
    @Autowired
    private CenterUserService centerUserService;
    @Autowired
    private FileService fdfsService;
    @PostMapping("uploadFace")
    public JSONResult uploadFace(
            String userId,
            MultipartFile file,
            HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        String path = "";
        // 开始文件上传
        if (file != null) {
            // 获得文件上传的文件名称
            String fileName = file.getOriginalFilename();
            if (StringUtils.isNotBlank(fileName)) {
                // 文件重命名
                String fileNameArr[] = fileName.split("\\.");
                // 获取文件的后缀名
                String suffix = fileNameArr[fileNameArr.length - 1];
                if (!suffix.equalsIgnoreCase("png") &&
                        !suffix.equalsIgnoreCase("jpg") &&
                        !suffix.equalsIgnoreCase("jpeg") ) {
                    return JSONResult.errorMsg("图片格式不正确!");
                }
                path = fdfsService.upload(file, suffix);
                System.out.println(path);
            }
        } else {
            return JSONResult.errorMsg("文件不能为空!");
        }
        if (StringUtils.isNotBlank(path)) {
            String finalUserFaceUrl = fileResource.getHost() + path;
            //更新图片地址到数据库
            Users userResult = centerUserService.updateUserFace(userId, finalUserFaceUrl);
            UsersVO usersVO = conventUsersVO(userResult);
            CookieUtils.setCookie(request, response, "user",
                    JsonUtils.objectToJson(usersVO), true);
        } else {
            return JSONResult.errorMsg("上传头像失败");
        }
        return JSONResult.ok();
    }
}
5、映射
@Component
@PropertySource("classpath:file.properties")
@ConfigurationProperties(prefix = "file")
public class FileResource {
    private String host;
        public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
}

Original: https://www.cnblogs.com/Tom-shushu/p/14470857.html
Author: Tom-shushu
Title: 分布式文件系统FastDFS简介、搭建、与SpringBoot整合实现图片上传

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/608577/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • spring boot 3 集成websocket

    第一步:导入依赖 org.springframework.bootspring-boot-starter-websocket 相比前面的章节,新增了websocket的依赖。 编写…

    Java 2023年5月30日
    078
  • jvm垃圾回收的过程

    垃圾回收的过程分为两步: 1.判断对象是否死亡 (1)引用计数器法: ①每当有一个对象引用是,计数器加一,当计数器为0是对象死亡 ②缺点:无法解决循环引用的问题,假设A引用B,B引…

    Java 2023年6月6日
    092
  • Java/Kotlin Double保留小数点后几位

    下面以保留2位小数,且按照四舍五入规则的例子 此方法得到的还是个double数值 double one = 5.864; BigDecimal two = new BigDecim…

    Java 2023年6月13日
    079
  • Git常用命令

    1.仓库 2.配置 3.增加/删除文件 4.代码提交 5.分支 6.标签 7.查看信息 8.远程同步 9.撤销 10.其他 1.仓库 将当前目录初始化为Git代码库 $ git i…

    Java 2023年6月8日
    087
  • 下载java 1.8

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年5月29日
    072
  • [学习笔记] 日期和时间

    日期(Date)和时间(Time)是计算机可以处理的重要数据; 日期代表日历中的某一天,由年/月/日组成,被看作是离散的数据; 时间代表某个时间点,由时/分/秒组成; 本地时间 我…

    Java 2023年6月5日
    077
  • Core Java 总结(字符和字符串类问题)

    所有代码均在本地编译运行测试,环境为 Windows7 32位机器 + eclipse Mars.2 Release (4.5.2) 2016-10-17 整理 字符,字符串类问题…

    Java 2023年5月29日
    086
  • 索引有什么分类?

    索引有什么分类? – 1、主键索引:名为primary的唯一非空索引,不允许有空值。 – 2、唯一索引:索引列中的值必须是唯一的,但是允许为空值。唯一索引和…

    Java 2023年6月5日
    077
  • 从零玩转SpringSecurity+JWT整合前后端分离

    从零玩转SpringSecurity+JWT整合前后端分离 2021年4月9日 · 预计阅读时间: 50 分钟 一、什么是Jwt? Json web token (JWT), 是为…

    Java 2023年6月9日
    081
  • kafka从入门到了解

    kafka从入门到了解 一、什么是kafka Apache Kafka是Apache软件基金会的开源的流处理平台,该平台提供了消息的订阅与发布的消息队列,一般用作系统间解耦、异步通…

    Java 2023年6月13日
    089
  • 那些年,我们见过的 Java 服务端乱象

    导读 查尔斯·狄更斯在《双城记》中写道:”这是一个最好的时代,也是一个最坏的时代。” 移动互联网的快速发展,出现了许多新机遇,很多创业者伺机而动;随着行业竞…

    Java 2023年5月29日
    0158
  • Spring Cloud Gateway 自定义断言(Predicate)

    1、类必须是Spring组件 Bean 2、类必须加上RoutePredicateFactory作为结尾 3、类必须继承AbstractRoutePredicateFactory …

    Java 2023年5月30日
    066
  • 十八、IO流(完结)

    十八、IO流 18.1 File 类 18.1.1 File 类介绍 java.io.File 类是 文件 和 目录 的 路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操…

    Java 2023年6月5日
    070
  • 【每天学一点-01】 在SpringBoot项目中使用Swagger2

    今天在做毕设的时候,发现在前后端分离的情况下,去调用接口数据时很不方便,然后回想过去,和同学一起做项目的时候,他负责后端,我负责前端,当时调用他的弄好的接口可以说是非常方便,主要是…

    Java 2023年6月5日
    090
  • 第三篇-用Flutter手撸一个抖音国内版,看看有多炫

    前言 前一篇已经开发了大部分框架,包含视频上下滑动播放,这次将上次未完成的数据显示友好显示,以及底部音乐走马灯特效,另外优化了加载数据的bug,在dart语言里 & 会自动…

    Java 2023年6月7日
    099
  • Java设计模式之(十四)——策略模式

    Define a family of algorithms, encapsulate each one, and make them interchangeable. Strate…

    Java 2023年5月29日
    051
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球