FastDFS分布式文件系统搭建

前提:

spring boot集成文件服务器

FastDfs集成与部署

一、安装FastDfs文件服务器

使用docker-compose安装FastDfs文件服务器(Linux CentorOs 7.x)

docker-compose.yml

version: '2'
services:
    fastdfs-tracker:
        hostname: fastdfs-tracker
        container_name: fastdfs-tracker
        image: season/fastdfs:1.2
        network_mode: "host"
        command: tracker
        volumes:
          - ./tracker_data:/fastdfs/tracker/data
    fastdfs-storage:
        hostname: fastdfs-storage
        container_name: fastdfs-storage
        image: season/fastdfs:1.2
        network_mode: "host"
        volumes:
          - ./storage_data:/fastdfs/storage/data
          - ./store_path:/fastdfs/store_path
        environment:
          - TRACKER_SERVER=xxx.xxx.xxx.xxx:22122
        command: storage
        depends_on:
          - fastdfs-tracker
    fastdfs-nginx:
        hostname: fastdfs-nginx
        container_name: fastdfs-nginx
        image: season/fastdfs:1.2
        network_mode: "host"
        volumes:
          - ./nginx.conf:/etc/nginx/conf/nginx.conf
          - ./store_path:/fastdfs/store_path
        environment:
          - TRACKER_SERVER=xxx.xxx.xxx.xxx:22122
        command: nginx

需要注意:
network_mode 必须是host, 原因是当上传文件时,tracker会把storage的IP和端口发给client,如果是bridge模式,则发送的是内网IP,client无法访问到。
image采用season/fastdfs:1.2 不要用lastest, 因为lastest不包含nginx服务,其他fasdfs镜像均没有season的精简。

nginx.conf(用于提供http的方式下载文件)

#user  nobody;
worker_processes  1;
 
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
 
#pid        logs/nginx.pid;
 
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
 
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
 
    #access_log  logs/access.log  main;
 
    sendfile        on;
    #tcp_nopush     on;
 
    #keepalive_timeout  0;
    keepalive_timeout  65;
 
    #gzip  on;
 
    server {
        listen       7003;
        server_name  localhost;
 
        #charset koi8-r;
 
        #access_log  logs/host.access.log  main;
 
        location /group1/M00 {
            root /fastdfs/storage/data;
            ngx_fastdfs_module;
        }
 
        #error_page  404              /404.html;
 
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
 }
}

注意事项:
com.github.tobato.fastdfs.exception.FdfsConnectException: 无法获取服务端连接资源:can't create connection to/127.0.0.1:23000
阿里云上使用fastDFS出现这个错误,原因在于
storage.conf 、mod_fastdfs.conf 、client.conf
由于tracker和storage在一台服务器上,这几个配置文件中对于tracker的ip地址都配置的0.0.0.0:22122,这样不行
将这三个配置文件对于tracker的ip配置改成公网IP,而且要在阿里云上配置开放22122和23000端口。tracker默认的8080http端口和storage默认的8888http端口也一并开放。
另外关闭防火墙

systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动

========================================================================

二、SpringBoot集成FastDfs文件服务器

springboot整合FastDfs文件服务器

  1. 导入依赖包
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.27.2</version>
        </dependency>
  1. FastDfs配置类
@Configuration
@Import(FdfsClientConfig.class) // 导入FastDFS-Client组件
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING) // 解决jmx重复注册bean的问题
public class FdfsConfiguration {
}
  1. 在application.yml文件中配置参数
ip: 192.168.11.12  #这只是一个例子,根据自己的ip进行更改

# 分布式文件系统FDFS配置
fdfs:
  soTimeout: 1500 #socket连接超时时长
  connectTimeout: 600 #连接tracker服务器超时时长
  trackerList: #TrackerList参数,支持多个,我这里只有一个,如果有多个在下方加- x.x.x.x:port
    - ${ip}:22122
  web-server-url: http://${ip}:7003/ #FDFS中的nginx的ip和port
  1. 编写FDFS工具类
@Component
public class FastDfsUtil {
    @Autowired
    private FastFileStorageClient fastFileStorageClient;
    @Autowired
    private FdfsWebServer fdfsWebServer;

    public String uploadFile(MultipartFile file) throws IOException {
        StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), null);
        String fullPath = storePath.getFullPath();
        getResAccessUrl(fullPath);
        return fullPath;

    }

    public String uploadFile(File file) {
        try {
            FileInputStream inputStream = new FileInputStream(file);
            StorePath storePath = fastFileStorageClient.uploadFile(inputStream, file.length(), FilenameUtils.getExtension(file.getName()), null);
            return storePath.getFullPath();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public byte[] downloadFile(String filePath) {
        StorePath storePath = StorePath.parseFromUrl(filePath);
        byte[] bytes = fastFileStorageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
        return bytes;
    }

    public Boolean deleteFile(String filePath) {
        if (StringUtils.isEmpty(filePath)) {
            return false;
        }
        try {
            StorePath storePath = StorePath.parseFromUrl(filePath);
            fastFileStorageClient.deleteFile(storePath.getGroup(), storePath.getPath());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    // 封装文件完整URL地址
    public String getResAccessUrl(String path) {
        String url = fdfsWebServer.getWebServerUrl() + path;
        System.out.println("上传文件地址为:\n" + url);
        return url;
    }
}
  1. 编写Controller进行测试
@RestController
@RequestMapping("/fastDfs")
public class FastDfsController {
    @Autowired
    private FastDfsUtil fastDfsUtil;

    @PostMapping("/upload")
    public void uploadFile(MultipartFile file) throws IOException {
        String s = fastDfsUtil.uploadFile(file);
        String resAccessUrl = fastDfsUtil.getResAccessUrl(s);
    }

    @GetMapping("/download")
    public void downloadFile(String filePath, HttpServletResponse response) throws IOException {
        byte[] bytes = fastDfsUtil.downloadFile(filePath);
        String fileName = "哈哈.jpg";
        response.setContentType("application/force-download");// 设置强制下载不打开
        //方式一
        // fileName=new String(fileName.getBytes(), "ISO8859-1")
        //方式二
        fileName = URLEncoder.encode(fileName, "utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        IOUtils.write(bytes, response.getOutputStream());
    }

    /**
     * 流媒体的方式播放视频,只能从头看到尾,不能手动点击重新看已经看过的内容
     * @param filePath
     * @param response
     * @throws IOException
     */
    @GetMapping("/play")
    public void streamMedia(String filePath, HttpServletResponse response) throws IOException {
        byte[] bytes = fastDfsUtil.downloadFile(filePath);
        IOUtils.copy(new ByteArrayInputStream(bytes), response.getOutputStream());
        response.flushBuffer();
    }

    @GetMapping("/delete")
    public void deleteFile(String filePath) {
        Boolean result = fastDfsUtil.deleteFile(filePath);
    }
}
1、所有文章未经授权禁止转载、摘编、复制或建立镜像,如有违反,追究法律责任。
2、本站文章部分来源注册用户发布或互联网收集而来,若有侵权,请邮件联系作者。
邮箱地址:wtao219@qq.com
THE END
分享
二维码
< <上一篇
下一篇>>