首页 > 其他分享 >百战商城项目---第11章 文件服务器 FastDFS 搭建

百战商城项目---第11章 文件服务器 FastDFS 搭建

时间:2023-11-27 23:57:47浏览次数:32  
标签:11 文件 -- FastDFS storage --- tracker fastdfs docker

1 简介

  FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。   FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。  

 2  FastDFS 组成

 FastDFS服务端有两个角色:跟踪器(tracker)和存储节点(storage)。跟踪器主要做调度工作,在访问上起负载均衡的作用。 存储节点存储文件,完成文件管理的所有功能:就是这样的存储、同步和提供存取接口,FastDFS同时对文件的metadata进行管理。所谓文件的meta data就是文件的相关属性,以键值对(key value)方式表示,如:width=1024,其中的key为width,value为1024。文件metadata是文件属性列表,可以包含多个键值对。   跟踪器和存储节点都可以由一台或多台服务器构成。跟踪器和存储节点中的服务器均可以随时增加或下线而不会影响线上服务。其中跟踪器中的所有服务器都是对等的,可以根据服务器的压力情况随时增加或减少。   为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。   在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。   当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。   FastDFS中的文件标识分为两个部分:卷名和文件名,二者缺一不可。  

 FastDFS 上传机制

FsatNFS 上传流程如下如

1. 定时向Tracker上传状态信息
2. 上传连接请求
3. 查询可用storage
4. 返回信息(storage的IP和端口)
5. 上传文件(file content和meta data)
6. 生成file_id
7. 将上传内容写入硬盘
8. 返回file_id(路径信息和文件名)
9. 存储文件信息

FastDFS架构

3 docker 安装

3.1 安装

拉取镜像

docker pull delron/fastdfs

创建挂载目录

mkdir -p /usr/local/docker/fastdfs/tracker /usr/local/docker/fastdfs/storage

创建 tracker 容器并启动

注意:tracker服务默认的端口为22122

docker run -d \
--name tracker \
--restart=always \
-p 22122:22122 \
-v /usr/local/docker/fastdfs/tracker:/var/fdfs \
-v /etc/localtime:/etc/localtime \
delron/fastdfs tracker

执行结果

root@ubuntu:~# docker run -d \
> --name tracker \
> --restart=always \
> -p 22122:22122 \
> -v /usr/local/docker/fastdfs/tracker:/var/fdfs \
> -v /etc/localtime:/etc/localtime \
> delron/fastdfs tracker
71f0f303600ff1b4ea1f775c3daee5140a0450b3bd2f51491a53186e84874d92

创建 storage 容器并启动

默认情况下在Storage服务中是帮我们安装了Nginx服务的,相关的端口为:

服务 默认端口
tracker 22122
storage 23000
Nginx 8888

docker run -d \
--name storage \
--restart=always \
-p 23000:23000 \
-p 8888:8888 \
-e TRACKER_SERVER=192.168.1.7:22122 \
-v /usr/local/docker/fastdfs/storage:/var/fdfs \
-v /etc/localtime:/etc/localtime \
delron/fastdfs storage

执行结果

root@ubuntu:~# docker run -d \
> --name storage \
> --restart=always \
> -p 23000:23000 \
> -p 8888:8888 \
> -e TRACKER_SERVER=192.168.1.7:22122 \
> -v /usr/local/docker/fastdfs/storage:/var/fdfs \
> -v /etc/localtime:/etc/localtime \
> delron/fastdfs storage
ab147903f7ca03b6eff30de8ae1fc4fdef7437ee05db9802b97492a3335b5d66

开启防火墙(如果没开启8888、22122、23000 端口的话)

3.2 测试

上传文件到storage

上传到上文中提到的存储位置的挂载目录下   xbxx.jpg

注意:会自动生成两个目录 data 和 logs

 进入storage 容器,执行上传文件上传命令

root@ubuntu:~# docker exec -it storage bash
[root@ab147903f7ca nginx-1.12.2]# ls
CHANGES  CHANGES.ru  LICENSE  Makefile  README  auto  conf  configure  contrib  html  man  objs  src
[root@ab147903f7ca nginx-1.12.2]# cd /var/fdfs/
[root@ab147903f7ca fdfs]# ls
data  lbxx.jpg  logs
[root@ab147903f7ca fdfs]# /usr/bin/fdfs_upload_file /etc/fdfs/client.conf lbxx.jpg
group1/M00/00/00/rBEAB2VkkOqAEaSXAAJuTFFJEGo015.jpg
[root@ab147903f7ca fdfs]#

说明:

# 上传文件的指令
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf 1.jpg  
# 上传文件返回的网络地址
group1/M00/00/00/rBEAB2VkkOqAEaSXAAJuTFFJEGo015.jpg

浏览器访问图片地址:

http://192.168.1.7:8888/group1/M00/00/00/rBEAB2VkkOqAEaSXAAJuTFFJEGo015.jpg

4 基于JavaAPI 调用

创建工程

pom.xml

<?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.chaoming</groupId>
    <artifactId>fastdfs-demo</artifactId>
    <version>1.0.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.3.12.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--分布式文件存储  fastDFS-->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.26.2</version>
        </dependency>
    </dependencies>

</project>

application.yml

server:
  port: 8888
spring:
  servlet:
    multipart: #如果不想限制文件的大小就把下面两个值设置成-1
      max-file-size: 5MB #设置单个文件的大小
      max-request-size: 10MB #设置单次请求的文件的总大小

fdfs:
    so-timeout: 5000 # 读取时间
    connect-timeout: 5000 #连接超时
    # 生成缩略图参数
    thumb-image:
      width: 50
      height: 50
  # 支持配置多个存储节点
    tracker-list:
      - 192.168.1.7:22122
    web-server-url: http://192.168.1.7:8888/

controller

package com.chaoming.demo.controller;

import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;

@RestController
@RequestMapping("/file")
@CrossOrigin//跨域的意思
public class FileController{
    @Resource
    private FastFileStorageClient fastFileStorageClient;


    @Value("${fdfs.web-server-url}")
    private String webServerUrl;

    /**
     * 文件上传
     * @Async开启异步
     * @return result
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public HashMap<String, String> upload(@RequestPart("file") MultipartFile file) {
        HashMap<String, String> result = new HashMap<>();
        try {
            //这里msg返回的是上传后的图片存储位置getFullPath()获取文件位置
            String fullPath = fastFileStorageClient.uploadFile(file.getInputStream(),
                    file.getSize(),
                    FilenameUtils.getExtension(file.getOriginalFilename()), null).getFullPath();
            result.put("msg", webServerUrl + fullPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 文件删除
     *
     * @param path
     * @return
     */
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    public HashMap<String, Object> delete(@RequestParam String path) {
        HashMap<String, Object> result = new HashMap<>();
        fastFileStorageClient.deleteFile(path);
        result.put("msg", "删除成功!");
        return result;
    }

}

启动类

package com.chaoming.demo;

import com.github.tobato.fastdfs.FdfsClientConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Import;

/**
 * @author Spqin
 * @version 1.0
 * @Date 2023-11-27 21:27
 */
@Import(FdfsClientConfig.class)
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class FastDFSApplicaiton {
    public static void main(String[] args) {
        SpringApplication.run(FastDFSApplicaiton.class,args);
    }
}

运行

 后台报错

[Request processing failed; nested exception is com.github.tobato.fastdfs.exception.FdfsConnectException: 无法获取服务端连接资源:
can't create connection to/172.17.0.1:23000] with root cause

这个错误的原因是,trackerclient通过我们配置的tracker-list 192.168.197.128:22122 服务来获取storageserver的时候,拿到的是172.17.0.1:23000配置,而这个地址在tracker容器中,是无法访问storage容器中的存储服务的。

出错的原因找到了,解决办法其实也能想的到,就是配置storage地址为虚拟机ip地址,而不是docker容器ip地址。

看了很多文章,这里最好用的办法就是在docker容器运行的时候,指定--network=host,表示docker容器与虚拟机共用一个主机地址,这样,也不需要暴露端口了。

 

重新创建容器

删除旧容器

root@ubuntu:~# docker rm -f tracker
tracker
root@ubuntu:~# docker rm -f storage
storage
root@ubuntu:~#

创建新的tracker 和 storage

注意一定要产出本地挂载的目录内的文件,不然会出错,玛德坑了我很久很久按。

#创建tracker
docker run -d \
--name tracker \
--restart=always \
-p 22122:22122 \
-v /usr/local/docker/fastdfs/tracker:/var/fdfs \
-v /etc/localtime:/etc/localtime \
--network=host \
delron/fastdfs tracker

#创建storage
docker run -d \
--name storage \
--restart=always \
-p 23000:23000 \
-p 8888:8888 \
-e TRACKER_SERVER=192.168.1.7:22122 \
-v /usr/local/docker/fastdfs/storage:/var/fdfs \
-v /etc/localtime:/etc/localtime \
--network=host \
delron/fastdfs storage

运行结果

root@ubuntu:/usr/local/docker/fastdfs/storage# docker run -d \
> --name tracker \
> --restart=always \
> -p 22122:22122 \
> -v /usr/local/docker/fastdfs/tracker:/var/fdfs \
> -v /etc/localtime:/etc/localtime \
> --network=host \
> delron/fastdfs tracker
WARNING: Published ports are discarded when using host network mode
069ed0f60573a117012d8ed1c2eb22a3e679079a392fe71799b5569a2253d176
root@ubuntu:/usr/local/docker/fastdfs/storage# docker run -d \
> --name storage \
> --restart=always \
> -p 23000:23000 \
> -p 8888:8888 \
> -e TRACKER_SERVER=192.168.1.7:22122 \
> -v /usr/local/docker/fastdfs/storage:/var/fdfs \
> -v /etc/localtime:/etc/localtime \
> --network=host \
> delron/fastdfs storage
WARNING: Published ports are discarded when using host network mode
9106c21f6725e1f85c873657bf7f0994c23423f32dac131a72eb3fa168bffde2
root@ubuntu:/usr/local/docker/fastdfs/storage#

再次运行成功

{
    "msg": "http://192.168.1.7:8888/group1/M00/00/00/wKgBB2VkuU6AD5KNAASsUpX1Tco160.png"
}

 访问生产的图片地址:

 

源码地址:fastdfs-demo: fastdfs-demo (gitee.com)

标签:11,文件,--,FastDFS,storage,---,tracker,fastdfs,docker
From: https://www.cnblogs.com/spqin/p/17859761.html

相关文章

  • 矩阵乘法 - 斐波那契前 n 项和
    题目题目描述求数列\(f_n=f_{n-2}+f_{n-1}\)的前\(n\)项的和,其中\(f_1=1,f_2=1\)。输出的数\(\bmod\10^9+7\)样例样例输入10样例输出143数据范围对于\(20\%\)的数据,有\(1\leqn\leq20\)对于\(100\%\)的数据,有\(1≤n<2^{63}\)分析这道题目矩阵乘法的......
  • 202311127
    C/S结构用户界面设计 【实验编号】10003809547j 图形用户界面设计【实验学时】8学时【实验环境】l 所需硬件环境为微机;l 所需软件环境为MicrosoftVisualStudio2013【实验内容】本次做的C/S框架的信息管理系统是一种比较经典的信息管理系统,实现了对于人员的的......
  • 7-5 有没有一捏
    7-5有没有一捏目录目录7-5有没有一捏目录题目背景代码思路代码运行结果题目背景一个神秘的数字解码器被用来识别和分析城市监控系统中的加密信号。这些信号用二进制代码表示,二进制值代表了不同类型的安全信息,当二进制值的最后一位为0时,代表该信号是安全的,不会造成网络威胁,如......
  • 线程-线程不安全
    线程不安全例如:线程不安全的HashMap在多线程环境下,使用HashMap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap。例如,执行以下代码会引起死循环。finalHashMap<String,String>map=newHashMap<>(2);Threadt=newThread(()->{for(......
  • Kotlin Notes - 5
    InKotlin,thetypesystemdistinguishesbetweenreferencesthatcanholdnull(nullablereferences)andthosethatcannot(non-nullablereferences).Forexample,aregularvariableoftypeStringcannotholdnull:vara:String="abc"//Regul......
  • 什么是 Two-Tier ERP strategy
    当一家公司为组织的不同部分实施不同的ERP系统时,行业将这种策略称为二层ERP策略。这种策略是由对大型复杂组织的需求与小型简单组织的需求非常不同的认识驱动的。通常作为子公司的较小组织,如果运行符合其需求的ERP解决方案,而不被其较大的姐妹组织所需的过度复杂的解决方案所......
  • 视频操作--3.视频追踪
    ......
  • 无涯教程-MySQL AVG Function函数
    MySQLAVG函数用于查找各种记录中某个字段的平均值。要了解AVG函数,请考虑一个employee_tbl表,该表具有以下记录-mysql>SELECT*FROMemployee_tbl;+------+------+------------+--------------------+|id|name|work_date|daily_typing_pages|+------+-......
  • Vue-mixin 混入处理
    概述再日常开发中,对于组件内部的方法多处存在相同的特点,往往会抽离出一个公共的方法方便调用,但是由于多个组件可能都需要用到这个方法,所以通过mixin混入的方式,将该方法独立抽离出来,方便多个组件的使用。步骤再src目录下创建一个mixins再该目录下创建一个xxxx.js文件编写对应......
  • AT-SMS
    AT+CSCA查看短信中心号码设置短信中心号码:AT+CSCA="+8613800250500"AT+CMGF1:文本模式0:pdu模式文本模式发送短信AT+CMGS="10010">短信内容ctrl+z结束发送ESC表示取消发送发送短信示例PDU模式(PDU建议小写,大写可能有的平台有问题)http://www.sendsms.cn/pdu......