FastDFS的使用

 

一、安装配置FastDFS

 查看容器:docker ps
 查看镜像:docker images
 进入容器:docker exec -it storage /bin/bash

1、拉取FastDFS镜像

 docker pull morunchang/fastdfs

2、运行tracker和storage

 tracker:负责文件管理负载均衡操作,控制中心(注册中心)
 storage:文件上传、文件下载、文件删除、文件修改……

运行tracker

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

运行storage

 docker run ‐d ‐‐name storage ‐‐net=host ‐e TRACKER_IP=虚拟机ip:22122 ‐e GROUP_NAME=group1 morunchang/fastdfs sh storage.sh

3、设置开机启动

 docker update ==restart=always tracker  设置tracker开机启动
 docker update ==restart=always storage 设置storage开机启动
 reboot 重启

4、修改nginx配置

进入storage容器内部,修改nginx.conf

 docker exec -it storage /bin/bash

进入后

 vi /etc/nginx/conf/nginx.conf

安装运行tracker和storage时默认已经安装配置好了nginx

  server {
        listen       8080;
        server_name localhost;
 
         #charset koi8-r;
 
         #access_log logs/host.access.log main;
 
        location / {
            root   html;
            index index.html index.htm;
        }
 
        location ~ /M00 {
                    root /data/fast_data/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;
        }
 

二、文件存储微服务

1、创建maven工程changgou-service-file

导入依赖

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

创建tracker配置文件fdfs_client.conf

 #tracker配置信息
 #连接操作时间
 connect_timeout = 60
 #网络请求操作时间
 network_timeout = 60
 charset = UTF‐8
 #tracker的http请求端口
 http.tracker_http_port = 8080
 #tracker的TCP通信端口
 tracker_server = 虚拟机IP:22122

创建核心配置文件application.yml

 spring:
  servlet:
    multipart:
       #上传文件最大大小
      max-file-size: 10MB
       #请求数据最大大小
      max-request-size: 10MB
   #服务名:file
  application:
    name: file
 server:
  port: 18084
 eureka:
  client:
     #eureka注册地址
    service‐url:
      defaultZone:http://127.0.0.1:7001/eureka
  instance:
    prefer-ip-address: true
 feign:
  hystrix:
    enabled: true

创建启动类FileApplication

//exclude:排除数据库自动加载
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient // 开启Eureka服务   客户端
public class FileApplication {
  // 引导类
  public static void main(String[] args) {
    //这里会创建spring容器
    SpringApplication.run(FileApplication.class, args);
  }
}

创建文件上传信息FastDFSFile,封装类

/**
 * @Author TeaBowl
 * @Date 2020/11/2 17:46
 * @Version 1.0
 * 封装文件上传信息
 *      时间:
 *      Author:
 *      type:
 *      size:
 *      附加信息:
 *      文件内容->文件的字节数组
 */
@Data   //getter&setter方法
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, String md5, String author) {
        this.name = name;
        this.content = content;
        this.ext = ext;
        this.md5 = md5;
        this.author = author;
    }

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

创建工具类FastDFSUtil

优化代码:抽取公共代码
测试
 /**
  * @Author TeaBowl @Date 2020/11/2 17:58 @Version 1.0
  * 实现FastDFS文件管理
  * 文件上传 文件下载 文件删除 文件信息获取 Storage信息获取 Tracker信息获取
  */
 public class FastDFSUtil {
   /**
    * 初始化加载Tracker连接信息
    */
   static {
     try {
       // tracker的配置信息:fdfs_client.conf
       // 查找classpath下的文件路径
       String filename = new ClassPathResource("fdfs_client.conf").getPath();
       // 加载Tracker连接信息
       ClientGlobal.init(filename);
    } catch (Exception e) {
       e.printStackTrace();
    }
  }
 
   /**
    * 文件上传
    *
    * @param fastDFSFile :上传的文件信息封装
    * @return
    */
   public static String[] upload(FastDFSFile fastDFSFile) throws Exception {
     // 附加参数
     NameValuePair[] metaList = new NameValuePair[1];
     metaList[0] = new NameValuePair("拍摄地址", "西安大雁塔");
 
     // 获取TrackerServer
     TrackerServer trackerServer = getTrackerServer();
     // 获取StotageClient
     StorageClient storageClient = getStorageClient(trackerServer);
 
     /**
      * 通过StorageClient访问Storage,实现文件上传,并且获取文件上传后的存储信息 上传文件的字节数组 文件的扩展名 附加参数
      *
      * <p>uploads[] uploads[0]:文件上传所存储的Storage的组名 group1 uploads[1]:文件上传所存储的Storage的文件名
      * M00/02/44/chawaner.jpg
      */
     String[] uploads =
         storageClient.upload_file(fastDFSFile.getContent(), fastDFSFile.getExt(), metaList);
     return uploads;
  }
 
   /**
    * 获取文件信息
    *
    * @param groupName :组名 group1
    * @param remoteFileName :文件存储路径 M00/00/00/wKiNb1-f9KWAFfThAACrggZCTjU215.png
    * @return file_info:文件信息
    * @throws Exception
    */
   public static FileInfo getFile(String groupName, String remoteFileName) throws Exception {
     // 获取TrackerServer
     TrackerServer trackerServer = getTrackerServer();
     // 获取StotageClient
     StorageClient storageClient = getStorageClient(trackerServer);
 
     // 获取文件信息
     FileInfo file_info = storageClient.get_file_info(groupName, remoteFileName);
     return file_info;
  }
 
   /**
    * 文件下载
    *
    * @param groupName :组名 group1
    * @param remoteFileName :文件存储路径 M00/00/00/wKiNb1-f9KWAFfThAACrggZCTjU215.png
    * @throws Exception
    * @return
    */
   public static InputStream downloadFile(String groupName, String remoteFileName) throws Exception {
     // 获取TrackerServer
     TrackerServer trackerServer = getTrackerServer();
     // 获取StotageClient
     StorageClient storageClient = getStorageClient(trackerServer);
 
     // 文件下载 字节数组->字节输入流
     byte[] buffer = storageClient.download_file(groupName, remoteFileName);
     ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
     return inputStream;
  }
 
   /**
    * 删除文件
    *
    * @throws Exception
    */
   public static void deleteFile(String groupName, String remoteFileName) throws Exception {
     // 获取TrackerServer
     TrackerServer trackerServer = getTrackerServer();
     // 获取StotageClient
     StorageClient storageClient = getStorageClient(trackerServer);
 
     // 删除文件
     storageClient.delete_file(groupName, remoteFileName);
  }
 
   /**
    * 获取Storage信息
    *
    * @throws Exception
    * @return
    */
   public static StorageServer getStorages() throws Exception {
     // 创建一个Tracker访问的客户端对象TrackerClient
     TrackerClient trackerClient = new TrackerClient();
     // 通过TrackerClient访问TrackerServer服务,获取连接信息
     TrackerServer trackerServer = trackerClient.getConnection();
 
     // 获取storage信息
     StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
     return storageServer;
  }
 
   /**
    * 获取Storage组的IP和端口信息
    *
    * @return
    */
   public static ServerInfo[] getServerInfo(String groupName, String remoteFileName)
       throws Exception {
     // 创建一个Tracker访问的客户端对象TrackerClient
     TrackerClient trackerClient = new TrackerClient();
     // 通过TrackerClient访问TrackerServer服务,获取连接信息
     TrackerServer trackerServer = trackerClient.getConnection();
     // 通过TackerServer的连接信息可以获取Storage的连接信息,创建StorageClient对象存储Storage的连接信息
     StorageClient storageClient = new StorageClient(trackerServer, null);
 
     // 获取storage组的IP和端口信息
     ServerInfo[] serverInfos =
         trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
     return serverInfos;
  }
 
   /**
    * 获取Tracker信息
    *
    * @throws Exception
    * @return
    */
   public static String getTrackerInfo() throws Exception {
     // 获取TrackerServer
     TrackerServer trackerServer = getTrackerServer();
 
     // 获取Tracker信息:IP、HTTP端口
     String ip = trackerServer.getInetSocketAddress().getHostString();
     // 8080
     int port = ClientGlobal.getG_tracker_http_port();
     String url = "http://" + ip + ":" + port;
     return url;
  }
 
   /**
    * 抽取的 获取TrackerServer代码
    *
    * @return
    * @throws Exception
    */
   public static TrackerServer getTrackerServer() throws Exception { 
   // 创建一个Tracker访问的客户端对象TrackerClient 
   TrackerClient trackerClient = new TrackerClient(); 
   // 通过TrackerClient访问TrackerServer服务,获取连接信息 
   TrackerServer trackerServer = trackerClient.getConnection(); 
   return trackerServer; 

​ 
 /** 
  * 抽取的 获取storageClient代码 
 
  * @return 
  * @throws Exception 
  */ 
 public static StorageClient getStorageClient(TrackerServer trackerServer) throws Exception { 
   // 通过TackerServer的连接信息可以获取Storage的连接信息,创建StorageClient对象存储Storage的连接信息 
   StorageClient storageClient = new StorageClient(trackerServer, null); 
   return storageClient; 

​ 
 // 主方法 测试 
 public static void main(String[] args) throws Exception { 
   // 获取文件信息 
   /*FileInfo fileInfo = getFile("group1", "M00/00/00/wKiNb1-f9KWAFfThAACrggZCTjU215.png"); 
   System.out.println("文件所在IP:" + fileInfo.getSourceIpAddr()); 
   System.out.println("文件大小:" + fileInfo.getFileSize());*/ 
​ 
   // 文件下载 
   /*// 获取文件输入流 
   InputStream is = downloadFile("group1", "M00/00/00/wKiNb1-f9KWAFfThAACrggZCTjU215.png"); 
   // 将文件写入到本地磁盘 文件存储至本地磁盘的位置 
   FileOutputStream os = new FileOutputStream("D:/fileDownload.png"); 
   // 定义一个缓冲区 
   byte[] buffer = new byte[1024]; 
   // 读取文件输入流到缓冲区 判断是否有数据   !=-1就是有数据 
   while (is.read(buffer) != -1) { 
     // 缓冲区写入到本地磁盘   1024个字节写入到fileDownload.png 
     os.write(buffer); 
   
   // 刷新缓冲区 
   os.flush(); 
   // 关闭输出流   os 
   os.close(); 
   // 关闭输入流 is 
   is.close();*/ 
​ 
   // 文件删除 
   // deleteFile("group1", "M00/00/00/wKiNb1-g0PWAFOI2AASGb8jq9KQ512.jpg"); 
​ 
   // 获取storage信息 
   /*StorageServer storageServer = getStorages(); 
   System.out.println("获取下标:"+storageServer.getStorePathIndex()); 
   System.out.println("获取IP信息:"+storageServer.getInetSocketAddress().getHostString());*/ 
​ 
   // 获取Storage组的IP和端口信息 
   // Storage组名 
   /*ServerInfo[] groups = getServerInfo("group1", "M00/00/00/wKiNb1-g1dKAWDCkAASGb8jq9KQ172.jpg"); 
   for (ServerInfo group : groups) { 
     // 获取IP 
     System.out.println(group.getIpAddr()); 
     // 获取端口 
     System.out.println(group.getPort()); 
   }*/ 
​ 
   // 获取Tracker信息 
   // System.out.println(getTrackerInfo()); 

}

文件删除方法,要在服务器的storage配置里加上下面这句,添加头信息:不要缓存

location ~ /M00 { add_header Cache-Control no-store; root /data/fast_data/data; ngx_fastdfs_module; }

 重启storage
    exit
    docker restart storage

创建FileUploadController

 动态获取url:FastDFSUtil.getTrackerInfo()
 @RestController
 @RequestMapping(value = "/upload")
 @CrossOrigin // 跨域
 public class FileUploadController {
   /**
    * 文件上传
    *
    * @param file:前端传来的参数
    * @return
    */
   @PostMapping
   public Result upload(@RequestParam(value = "file")MultipartFile file) throws Exception {
     /** 封装文件信息 文件名 文件字节数组 文件扩展名 */
     FastDFSFile fastDFSFile = new FastDFSFile(
             file.getOriginalFilename(),
             file.getBytes(),
             StringUtils.getFilenameExtension(file.getOriginalFilename()));
 
     // 调用FastDFSUtil工具类将文件传入到FastDFS中
     String[] uploads = FastDFSUtil.upload(fastDFSFile);
     //拼接访问地址:url = http://192.168.141.111:8080/group1/M00/00/00/mksnjdlkakjiodnsjbja.jpg
     //String url = "http://192.168.141.111:8080"+"/"+uploads[0]+"/"+uploads[1];
     String url = FastDFSUtil.getTrackerInfo()+"/"+uploads[0]+"/"+uploads[1];
     return new Result(true, StatusCode.OK, "上传成功!",url);
  }
 }
 

 

posted @ 2020-11-03 13:15  茶碗儿  阅读(182)  评论(0)    收藏  举报
点击这里跳转到-->【茶碗儿CSDN】