分布式文件存储与数据缓存 FastDFS(二)

简介: 分布式文件存储与数据缓存 FastDFS(二)

四、SpringBoot操作FastDFS实现文件上传(基本版)

由GitHub大牛tobato在原作者YuQing与yuqih发布的JAVA客户端基础上进行了大量重构工作,并于GitHub上发布了FastDFS-Client1.26.5。

主要特性

  1. 对关键部分代码加入了单元测试,便于理解与服务端的接口交易,提高接口质量
  2. 将以前对byte硬解析风格重构为使用对象+注解的形式,尽量增强了代码的可读性
  3. 支持对服务端的连接池管理
  4. 支持上传图片时候检查图片格式,并且自动生成缩略图
  5. 在SpringBoot当中自动导入依赖

1、创建springboot项目(2.7.0),导入FastDFS依赖jar

<dependency>
  <groupId>com.github.tobato</groupId>
  <artifactId>fastdfs-client</artifactId>
  <version>1.26.5</version>
</dependency>

2、添加配置

####分布式文件系统配置###########
fdfs:
  so-timeout: 1500
  connect-timeout: 600
  thumb-image:       #缩略图生成参数
    width: 150
    height: 150
  tracker-list:       #TrackerList参数,支持多个
    - 192.168.66.100:22122
   # - 192.168.66.101:22122

3、编写测试类实现文件上传和文件下载

package com.zj;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.io.*;
@SpringBootTest
class FastdfsApplicationTests {
    //通过FastDFS的客户端对象完成对文件系统的操作
    @Resource
    private FastFileStorageClient fastFileStorageClient;
    //测试上传文件
    @Test
    public void upload() throws FileNotFoundException {
        //1.先读取本地文件
        File file = new File("D:\\aaa.jpg");
        //2.创建传输文件输入流
        FileInputStream fileInputStream = new FileInputStream(file);
        //3.文件上传
        /*
         * 参数一:文件输入流
         * 参数二:文件大小
         * 参数三:文件拓展名
         * 参数四:描述文件的元数据(指定文件上传的位置)
         */
        StorePath storePath = fastFileStorageClient.uploadFile(fileInputStream, file.length(), "jpg", null);
        //4.将卷名和文件名一起打印
        System.out.println("上传文件的地址:"+storePath.getFullPath());
        System.out.println("文件卷名:"+storePath.getGroup());
        System.out.println("文件名:"+storePath.getPath());
    }
    //文件下载
    @Test
    public void download() throws IOException {
       //1.下载文件
        /*
         * 参数一:文件处于存储节点的卷名
         * 参数二:文件在存储节点的文件名
         * 参数三:下载的回调函数
         */
        byte[] downloadFile = fastFileStorageClient.downloadFile("group1", "M00/00/00/wKhCZGS2WGaAYKOuADcAPt_yJDw957.jpg", new DownloadByteArray());
         //2.创建文件输出流,并指定文件下载的位置
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\aaa.jpg");
         //3.将文件输出流写文件到磁盘
        fileOutputStream.write(downloadFile);
        //4.刷新
        fileOutputStream.flush();
        //5.关闭流
        fileOutputStream.close();
    }
}

五、spring boot整合FastDFS实现文件上传(完整版)

1、引入Thymeleaf视图解析器和文件上传客户端对象

<!--fastdfs-->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.26.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

注意:

使用wangeditor富文本编辑器的前提是引入Thymeleaf模板。

2、通过CDN在前端页面引入wangEditor富文本编辑器

<script type="text/javascript" src="https://unpkg.com/wangeditor/dist/wangEditor.min.js"></script>

3、创建编辑器基本骨架

<div id="div1">
    <p>欢迎使用 <b>wangEditor</b> 富文本编辑器</p>
</div>
<script type="text/javascript">
    const E = window.wangEditor;
    const editor = new E('#div1')
    editor.create();
</script>

4、创建文件上传的Controller控制器

package com.zj.controller;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
@RestController
public class uploadController {
    @Resource
    private FastFileStorageClient fastFileStorageClient;
    //图片上传
    @PostMapping("/upload")
    public void upload(MultipartFile file) throws IOException {
      //1.判断文件是否为空
        if(file != null){
            //2.获取上传的图片的名字
            String originalFilename = file.getOriginalFilename();
            //3.获取上传的图片的扩展名
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            //4.上传图片
            StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), suffix, null);
            System.out.println("上传的文件的路径:"+storePath.getFullPath());
            //5.上传的文件路径需要保存到数据库中
            //……
        }
    }
}

文件上传的请求方式必须是post

5、完整的index.html页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
    <script type="text/javascript" src="https://unpkg.com/wangeditor/dist/wangEditor.min.js"></script>
</head>
<body>
<div id="div1">
    <p>欢迎使用 <b>wangEditor</b> 富文本编辑器</p>
</div>
<script type="text/javascript">
    const E = window.wangEditor;
    const editor = new E('#div1');
    //指定文件上传的服务路径
    editor.config.uploadImgServer = "/upload";
    //文件参数名
    editor.config.uploadFileName = "file";
    //限制文件上传的大小和类型 2M
    editor.config.uploadImgMaxSize = 2 * 1024 * 1024;
    //文件上传的类型
    editor.config.uploadImgAccept = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
    editor.create();
</script>
</body>
</html>

6、启动项目,上传图片即可

六、FastDFS整合Nginx

 Nginx服务器是一个高性能的web服务器与反向代理服务器。

FastDFS集成Nginx的2个原因

  1. 为分布式文件系统提供Http服务支持

通过Nginx的web服务代理访问分布式文件系统的存储节点,从而实现通过http请求访问存储节点资源。

注意:

src 属性值图像文件的 URL。也就是引用该图像的文件的的绝对路径或相对路径。

 2.解决复制延迟问题

由于FastDFS的同卷的存储节点之间需要同步,当文件尚未同步完成时,访问请求到达改节点,获取的数据将是未同步完的不完整数据,即为复制延迟问题。通过Nginx检测请求的存储节点的数据,若该存储节点的数据尚未同步完成,则将请求转发至数据的原存储节点,从而解决复制延迟问题。

环境搭建

下载Fastdfs的Nginx模块包

#选择安装位置
cd /usr/local
#下载文件(或者使用本文章已经下载好的文件)
wget https://github.com/happyfish100/fastdfs-nginx-module/archive/V1.22.tar.gz
#解压文件
tar -zxvf V1.22.tar.gz

在ginx-1.20.2目录下安装Nginx依赖文件

yum install -y gcc gcc-c++ zlib zlib-devel openssl openssl-devel pcre pcre-devel gd-devel epel-release

配置Nginx服务器

#建立Makefile文件,检查Linux系统环境以及相关的关键属性。添加fastdfs-nginx-module-1.22模块到nginx
./configure --add-module=/usr/local/fastdfs-nginx-module-1.22/src/
#编译项目,主要将gcc源代码编译成可执行的目标文件
make
#根据上一步骤编译完成的数据安装到预定的目录中。之前安装过ngxin的话不需要再安装
make install

注意:

  • –add-module:为nginx添加一个fastdfs-nginx-module模块,值为该模块在当前系统的路径
  • –prefix:指定nginx安装位置

将Fastdfs软件包里面的http.conf和mime.types拷贝到/etc/fdfs目录下

cp /usr/local/fastdfs-6.06/conf/mime.types /etc/fdfs/
cp /usr/local/fastdfs-6.06/conf/http.conf /etc/fdfs/

配置Nginx的fastdfs模块,并编辑文件

#拷贝文件
[root@localhost opt]cp /usr/local/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf /etc/fdfs/
[root@localhost fdfs] vim mod_fastdfs.conf
#保存日志目录
base_path=/data/fastdfs/storage   
#tracker 服务器的 IP 地址以及端口号
tracker_server=192.168.66.100:22122 
#文件url中是否有group 名
url_have_group_name = true      
#存储路径
store_path0=/data/fastdfs/storage  
group_count = 1            #设置组的个数
#然后在末尾添加分组信息,目前只有一个分组,就只写一个
[group1]
group_name=group1
storage_server_port=23000
store_path_count=1
store_path0=/data/fastdfs/storage

配置Nginx

server {
  listen    80;
  server_name  localhost;
  location ~ /group[1-3]/M00 {
    alias /data/fastdfs/storage/data;
     ngx_fastdfs_module;
   }
  # 根目录下返回403
  location = / {
     return 403;
   }
  # log file
  access_log  logs/img_access.log access;
}

启动Ningx服务

# 进入sbin目录
[root@tracker nginx]# cd sbin/
# 启动服务 -c:指定配置文件
[root@tracker sbin]# ./nginx -c /usr/local/nginx/conf/nginx.conf

查看服务启动情况

[root@tracker sbin]# ps -ef | grep nginx

启动追踪服务与存储节点服务

[root@tracker sbin]# fdfs_trackerd /etc/fdfs/tracker.conf start
[root@tracker sbin]# fdfs_storaged /etc/fdfs/storage.conf start

上传图片测试

将图片上传至linux系统后,使用指令上传至分布式文件系统

[root@localhost /]# fdfs_upload_file /etc/fdfs/client.conf pdx.jpg
group1/M00/00/00/wKhCZGS6zneAUxGKAANsTCZQKGY401.jpg

通过浏览器远程访问

http://192.168.66.100/group1/M00/00/00/wKhCZGS6zneAUxGKAANsTCZQKGY401.jpg


相关文章
|
7月前
|
Web App开发 存储 缓存
如何精准清除特定类型或标签的缓存数据?
如何精准清除特定类型或标签的缓存数据?
579 57
|
9月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
4月前
|
存储 监控 算法
117_LLM训练的高效分布式策略:从数据并行到ZeRO优化
在2025年,大型语言模型(LLM)的规模已经达到了数千亿甚至数万亿参数,训练这样的庞然大物需要先进的分布式训练技术支持。本文将深入探讨LLM训练中的高效分布式策略,从基础的数据并行到最先进的ZeRO优化技术,为读者提供全面且实用的技术指南。
|
11月前
|
SQL
【YashanDB知识库】手工迁移Doris数据到崖山分布式
【YashanDB知识库】手工迁移Doris数据到崖山分布式
|
11月前
|
存储 分布式计算 负载均衡
数据分布式存储:在海量数据面前,我们如何站稳脚跟?
数据分布式存储:在海量数据面前,我们如何站稳脚跟?
1517 1
|
6月前
|
存储 缓存 监控
一次缓存引发的文件系统数据不一致问题排查与深度解析
本文详述了一次由自研分布式文件系统客户端 EFC 的缓存架构更新所引发的严重数据不一致问题的完整排查过程。
一次缓存引发的文件系统数据不一致问题排查与深度解析
|
9月前
|
数据采集 存储 NoSQL
基于Scrapy-Redis的分布式景点数据爬取与热力图生成
基于Scrapy-Redis的分布式景点数据爬取与热力图生成
512 67
|
9月前
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
302 32
|
9月前
|
SQL 存储 OLAP
数据外置提速革命:轻量级开源SPL如何用文件存储实现MPP级性能?
传统交易型数据库在分析计算中常遇性能瓶颈,将数据迁至OLAP数据仓库虽可缓解,但成本高、架构复杂。SPL通过轻量级列存文件存储历史数据,提供强大计算能力,大幅简化架构并提升性能。它优化了列式存储、数据压缩与多线程并行处理,在常规及复杂计算场景中均表现优异,甚至单机性能超越集群。实际案例中,SPL在250亿行数据的时空碰撞问题上,仅用6分钟完成ClickHouse集群30分钟的任务。
数据外置提速革命:轻量级开源SPL如何用文件存储实现MPP级性能?