传统的Web应用的文件管理方式,例如,图片和视频文件的上传和使用等,大多数是将文件存储在服务器本地,这种方式已经不能适用微服务应用的使用.一方面,微服务应用发布在分布式环境中,随时随地的都可以进行多副本的部署,所以他的媒体文件的存放必须有一个统一的地方;另一方面,建立一个独立而高效的文件系统,也是高可用和高性能的应用平台一个有机组成方面
我们将使用开源的FastDFS这个轻量级的分布式文件系统,搭建一个高可用并且可以持续扩展的分布式文件系统

FastDFS安装

FastDFS分为服务端和客户端API两个部分,服务端又称之为跟踪器(Tracker)和存储节点(Storage)两个角色.跟踪器主要负责服务调度,起着负载均衡的作用.存储节点主要负责文件的存储,读取和同步等功能.客户端API提供了文件上传,下载和删除等操作方法.典型的FastDFS服务器的网络拓扑结构如图所示,客户端链接追踪器服务器集群,跟踪器管理存储节点集群,为客户端提供可用的存储节点.
在这里插入图片描述

FastDFS支持动态扩展,当资源将要耗尽的时候,可以通过增加新卷或者新组的方式增加更多的存储节点
存储节点的文件使用了分卷或者分组的组织方式,所以一个文件的标识由卷名或者组名,路径和文件名组成
为了演示使用FastDFS我们使用一个Linxu系统.
配置是centos7, 作为TrackerServer,StorageServer

下面将按照步骤说明安装的过程,由于使用Nginx提供文件的浏览访问功能,同时也需要安装Nginx服务,对于文件的组织方式使用了分组的方法,并且建立了一个分组:group1

  • 下载FastDFS5.0.1
    下载地址:https://github.com/happyfish100
  • 下载Nginx1.7.0
    wget http://nginx.org/download/nginx-1.7.0.tar.gz
  • 下载fastdfs-nginx-module_v1.16
    https://github.com/happyfish100/fastdfs-nginx-module

安装FastDFS

在一台服务器上安装FastDFS和Nginx,其中FastDFS使用默认的安装配置,Nginx使用了自定义的安装配置
要执行安装指令,系统中必须具备编译环境,如果系统中没有编译环境,可以使用一下指令增加编译环境

  • yum -y install gcc gcc+ gcc-c++ openssl eopnssl-devel pcre pcre-deve
  • 下载最新版本的各个安装包
wget https://github.com/happyfish100/fastdfs-nginx-module/archive/master.zip
 wget https://github.com/happyfish100/libshmcache/archive/master.zip
wget https://github.com/happyfish100/libfastcommon/archive/master.zip
wget https://github.com/happyfish100/fastdfs/archive/master.zip

然后分别使用unzip解压
在这里插入图片描述

  • make.sh
  • make.sh install
  • 配置文件复制 cp conf/* /etc/fdfs/

配置启动trackerd

  • 修改trackerd.conf, 将base_path改为/data/fastdfs
  • 新建数据,日志目录 mkdir -p /data/fastdfs
  • 启动tracker /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
  • 查看进程
[lidengyin@ldy ~]$ sudo netstat -anp | grep tracker
[sudo] password for lidengyin: 
tcp        0      0 0.0.0.0:22122           0.0.0.0:*               LISTEN      25401/fdfs_trackerd 
tcp        0      0 192.168.0.52:22122      121.36.145.230:48668    ESTABLISHED 25401/fdfs_trackerd 

配置并启动storaged

  • cp storage.conf.sample storage.conf
  • 修改storage,conf ,将base_path修改为/data/fastdfs/storage
  • 修改storage.conf,将tracker_server修改为xxx.xxx.xxx.xxx:22122
  • 创建storaged数据以及日志目录, mkdir -p /data/fastdfs/storage
  • 启动storage, /usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
  • 查看启动状态
[lidengyin@ldy ~]$ sudo netstat -anp | grep storage
tcp        0      0 0.0.0.0:23000           0.0.0.0:*               LISTEN      4267/fdfs_storaged  
tcp        0      0 192.168.0.52:48668      121.36.145.230:22122    ESTABLISHED 4267/fdfs_storaged  

上传文件测试

[lidengyin@ldy ~]$ fdfs_upload_file /etc/fdfs/client.conf ~/time.image 
group1/M00/00/00/eSSR5l9BS2-ALceJAACIK0j0AKw7.image
[lidengyin@ldy ~]$ 

在fdfs安装时的错误

  • 问题1: …/common/fdfs_global.c:20:31: fatal error: fastcommon/logger.h: No such file or directory
    #include “fastcommon/logger.h”
  • 解决方法1:
    先安装libfastcommon重复./make ./make install

安装Nginx

配置FastDFS-nginx-module模块

  • 解压安装
  • 拷贝配置文件 cp mod_fastdfs.conf /etc/fdfs/
  • 编辑配置文件将追踪服务器tracker_Server设置为tracker_server=xxx.xxx.x.xxx:22122
  • 编辑配置文件,将url_have_group_name=false改为true,url中使用group名称
  • 编辑配置文件,将存储路径store_path0改为store_path0=/data/fastdfs/storage/

Nginx安装

  • Nginx解压
  • 安装Nginx并且添加fastdfs模块: ./configure --prefix=/usr/local/nginx --add-module=/usr/local/software/fastdfs-nginx-module/src
  • make
  • make install
  • 版本: nginx -V
[lidengyin@ldy ~]$ nginx -V
nginx version: nginx/1.9.9
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
configure arguments: --add-module=/usr/local/software/fastdfs-nginx-module-master/src/

配置nginx

  • 打开配置文件 sudo vim /usr/local/nginx/conf/nginx.conf
  • 完整配置文件如下
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       8888;
        server_name  121.36.145.230;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location /group1/M00 {
            root /data/fastdfs/storage;
            ngx_fastdfs_module;
        }

注意这里的8888是和storage服务器一致的

使用module后无法访问nginx的问题

复制 fdfs/conf/http.conf 以及 fdfs/conf/mime.types到/etc/fdfs才可以

客户端配置

maven依赖

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

配置文件

connect_timeout = 2
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 80
http.anti_steal_token = no
http.secret_key = FastDFS1234567890

tracker_server = 121.36.145.xx:22122
tracker_server = 121.36.145.xx:22122

上传代码

    @ApiOperation(value = "测试上传方法")
    @PostMapping(value = "/upload/file/mine")
    @CrossOrigin(origins = "*", allowedHeaders = "*", methods ={RequestMethod.POST,RequestMethod.GET,RequestMethod.PUT,RequestMethod.DELETE,RequestMethod.OPTIONS} )
    @ResponseBody
    public ServerResponse fileUpload(MultipartFile file){
        String conf_filename="fdfs_client.conf";
        try {
            ClientGlobal.init(conf_filename);
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();
            StorageServer storageServer = null;
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
//            NameValuePair nvp[] = new NameValuePair[]{
//
//            }
            String fileName = ResourceUtils.getURL("").getPath()+UUID.randomUUID().toString()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            System.out.println("file: "+fileName);
            File upload_temp_file= new File(fileName);
            file.transferTo(upload_temp_file);


            String fileIds[] = storageClient.upload_file(upload_temp_file.getAbsolutePath() ,null, null);
            String path = PropertiesUtil.getProperty("fastdfs.tracker_servers")+"/"+fileIds[0]+"/"+fileIds[1];

            return ServerResponse.createBySuccess(path);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        return ServerResponse.createByError("文件存储失败");
    }

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐