欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FastDFS改造文件上传

程序员文章站 2022-06-03 08:51:37
...

1.什么是分布式文件系统?

分布式文件系统(DFS):指文件系统管理的物理存储资源不一定直接在本地节点上,而是通过计算机网络与节点连接。

2. 什么是FastDFS?

FastDFS是淘宝的余庆先生开发的轻量级,高性能的开源分布式文件系统。
FastDFS改造文件上传两个主要的角色:Tracker Server(跟踪服务器) 和 Storage Server(存储服务器)

  • Tracker Server:跟踪服务器,主要负责调度storage节点与client通信, 在访问上起负载均衡的作用,和记录storage节点的运行状态,是连接 client和storage节点的枢纽。
  • Storage Server:存储服务器,保存文件和文件的meta data(元数据),每个storage server会启动一个单独的线程主动向Tracker cluster 中每个tracker server报告其状态信息,包括磁盘使用情况,文件同步情况 及文件上传下载次数统计等信息
  • Group:文件组,多台Storage Server的集群。上传一个文件到同组内的 一台机器上后,FastDFS会将该文件即时同步到同组内的其它所有机器上, 起到备份的作用。不同组的服务器,保存的数据不同,而且相互独立,不 进行通信。
  • Tracker Cluster:跟踪服务器的集群,有一组Tracker Server(跟踪服务 器)组成。
  • Storage Cluster :存储集群,有多个Group组成。

3.配置与使用

使用开源的FastDFS客户端,支持SpringBoot2.0 tobato/FastDFS_client

3.1 引入依赖

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

3.2 引入配置类

/**
 * @author fenco
 */
@Configuration
@Import(FdfsClientConfig.class)

/**
 *解决JMX重复注册bean问题
 */
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastClientImporter {
}

3.3 编写FastDFS属性

在application.yml中进行配置

fdfs:
 so-timeout: 1501 # 超时时间
 connect-timeout: 601 # 连接超时时间
 thumb-image: # 缩略图
   width: 60
   height: 60
 tracker-list: # tracker地址:你的虚拟机服务器地址+端口(默认是22122- 192.168.43.114:22122

3.4 配置host文件

将来通过域名:image.leyou.com这个域名访问fastDFS服务器上的图片资源。所以,需要代理到虚拟机地址: 配置hosts文件,使image.leyou.com可以访问fastDFS服务器

192.168.34.114  image.leyou.com

3.5 改造上传逻辑

/**
 * @author FENCO
 * @date 2020/2/4 8:35
 * @company HOWSO
 */
@Service
public class UploadService {

    //定义一个静态常量,列举用到的contentType
    private static final List<String> CONTENT_TYPES = Arrays.asList("image/gif","image/jpeg");

    private static final Logger LOGGER = LoggerFactory.getLogger(UploadService.class);

    @Autowired
    private FastFileStorageClient storageClient;



    public String uploadImage(MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        //校验文件类型
        String contentType = file.getContentType();
        if (!CONTENT_TYPES.contains((contentType))) {
            //不包含,则参数不合法
//            LOGGER.info("文件类型不合法:" + originalFilename);
            //更优雅的表达:{}占位符
            LOGGER.info("文件类型不合法:{}", originalFilename);
            return null;
        }
        try {
            //校验文件内容
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            if (bufferedImage == null) {
                LOGGER.info("文件内容不合法:{}", originalFilename);
            }
            //保存到文件的服务器
//            file.transferTo(new File("G:\\HEIMA\\leyou\\images" + originalFilename));
            String ext = StringUtils.substringAfterLast(originalFilename, ".");
            StorePath storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), ext, null);
            //返回url,进行回显
//            return "http://image.leyou.com/" + originalFilename;
            return "http://image.leyou.com/" + storePath.getFullPath();
        } catch (IOException e) {
            LOGGER.info("服务器内部错误:" + originalFilename);
            e.printStackTrace();
        }
        return null;
    }
}

3.6 测试

相关标签: 开发 小技巧