文档章节

分布式文件系统FastDFS安装部署(高可用)

MaxBill
 MaxBill
发布于 11/20 13:34
字数 4301
阅读 3526
收藏 145

本文会搭建一个适合低业务访问业务量的高可用的FastDFS集群环境:两个Tracker服务,一个storage group中两个storage服务节点;该方案仅适用于业务访问量较低的环境下。对于大量业务系统的高并发访问,为了保证存储系统正常工作一般的架构思路:安装多个Tracker服务(至少两个,根据业务量调整),搭建多个storage group(至少两个,根据业务量调整),每个storage group中多个storage node(至少两个,做数据的冗余备份,进行容灾机制,而且node必须在不同的机器上)

一、FastDFS简介

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。

FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

FastDFS服务端有两个角色:跟踪器(tracker)和存储节点(storage)。跟踪器主要做调度工作,在访问上起负载均衡的作用。

存储节点存储文件,完成文件管理的所有功能:就是这样的存储、同步和提供存取接口,FastDFS同时对文件的metadata进行管理。所谓文件的meta data就是文件的相关属性,以键值对(key value)方式表示,如:width=1024,其中的key为width,value为1024。文件metadata是文件属性列表,可以包含多个键值对。

跟踪器和存储节点都可以由一台或多台服务器构成。跟踪器和存储节点中的服务器均可以随时增加或下线而不会影响线上服务。其中跟踪器中的所有服务器都是对等的,可以根据服务器的压力情况随时增加或减少。

为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。

在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。

当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。

FastDFS中的文件标识分为两个部分:卷名和文件名,二者缺一不可。

———简介摘自百度百科

二、FastDFS原理介绍

1.文件上传

FastDFS以客户端库的方式提供基本的文件访问接口如upload、download、append、delete等,Storage 服务会定时的向Tracker服务发送自己的存储信息。当Tracker 服务集群中的Tracker 服务是多个时,各个Tracker服务之间的关系是对等的,因此客户端上传时会任意选择一个Trackre服务。当Tracker服务收到客户端上传文件请求时,会为该文件分配一个可以存储文件的group,当选定了group后就要决定给客户端分配group中的哪一个storage服务。当分配好storage 服务后,客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录。然后为文件分配一个文件ID标示,然后根据以上的信息生成文件名存储文件。

2.文件同步

上传文件后,客户端将文件写到group内的一个storage 服务即为上传文件成功,storage服务写完文件后,会由后台线程将文件同步至同group内的其他的storage 服务节点上。 每个storage服务写文件后,会同时写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内的所有server的始终保持同步。最后Storage服务的同步进度会作为元数据的一部分汇报到tracker服务上,tracker服务在选择读storage的时候会以同步进度作为参考指标。

3.下载文件

当下载文件时,客户端先询问tracker服务下载文件的storage,参数为文件标识(卷名和文件名);然后tracker向客户端返回一台可用的storage;最后客户端直接和storage通讯完成文件下载。

三、部署环境准备

1.环境说明

操作系统CentOS7.6

fastdfs版本:6.01

nginx版本:1.16.1

keepalived版本:2.0.19

2.系统依赖

 gcc gcc-c++ perl pcre pcre-devel zlib zlib-devel openssl openssl-devel libnl libnl-devel

3.软件环境

libevent下载地址:http://libevent.org/

nginx下载地址:http://nginx.org/en/download.html

keepalived下载地址:https://www.keepalived.org/software/

fastdfs下载地址:https://github.com/happyfish100/fastdfs/releases

libfasttcommon下载地址:https://github.com/happyfish100/libfastcommon/releases

fastdfs-nginx-module下载地址:https://github.com/happyfish100/fastdfs-nginx-module/releases

4.机器及网络环境规划

Fdfs Server VIP:         192.168.100.110

Tracker Server1:         192.168.100.111

Tracker Server2:         192.168.100.112

Storage Group1 Node1:    192.168.100.111

Storage Group1 Node2:    192.168.100.112

5.防火墙设置

关闭系统防火墙:sudo systemctl stop firewalld && systemctl disable firewalld

四、Keepalived服务安装配置

1.下载Keepalived源码包

官网地址:https://www.keepalived.org/

下载地址:https://www.keepalived.org/software/keepalived-2.0.19.tar.gz

2.上传并解压Keepalived源码包

tar -zxvf keepalived-2.0.19.tar.gz

3.编译Keepalived准备

进入解压目录:cd keepalived-2.0.19

执行编译准备:./configure --prefix=/work/keepalived

注意:一定要有gcc和openssl编译相关的依赖

4.编译安装Keepalived

make && make install

5.安装配置Keepalived

keepalived启动时会从/etc/keepalived/中相关的目录下查找keepalived.conf配置文件,因此将keepalived安装录/usr/local/keepalived/etc/keepalived.conf 拷贝到/etc/keepalived/中。

mkdir /etc/keepalived/

cp /work/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf

cp /work/keepalived/etc/sysconfig/keepalived /etc/sysconfig/keepalived

6.设置Keepalived开机启动项

systemctl enable keepalived

然后就能使用systemctl start/stop/status keepalived管理keepalived了

7.配置Keepalived服务

192.168.100.111机器上配置:vi /etc/keepalived/keepalived.conf

vrrp_script check_nginx {
       interval 3
       script "/work/script/check_nginx.sh"
}

 
vrrp_instance fdfs_server {
       state MASTER
       interface enp0s3
       virtual_router_id 110
       priority 100
       advert_int 3
       authentication {
            auth_type PASS
            auth_pass password
       }
       virtual_ipaddress {
            192.168.100.110
       }
       track_script {
            check_nginx
       }
}

192.168.100.112机器上配置:vi /etc/keepalived/keepalived.conf

vrrp_script check_nginx {
       interval 3
       script "/work/script/check_nginx.sh"
}

 
vrrp_instance fdfs_server {
       state BACKUP
       interface enp0s3
       virtual_router_id 110
       priority 90
       advert_int 3
       authentication {
            auth_type PASS
            auth_pass password
       }
       virtual_ipaddress {
            192.168.100.110
       }
       track_script {
            check_nginx
       }
}

8.编写nginx服务检测脚本

vi /work/script/check_nginx.sh

#!/bin/bash
active_status=`netstat -lntp|grep nginx|wc -l`
if [ $active_status -gt 0 ]; then
    exit 0
else
    exit 1
fi

 然后给脚本赋予执行权限:chmod +x /work/script/check_nginx.sh

9.修改内核参数

vi /etc/sysctl.conf

增加如下内容:

net.ipv4.ip_nonlocal_bind = 1  #允许忽视VIP的存在

net.ipv4.ip_forward = 1  #允许转发

sysctl --system 使配置生效

五、安装FastDFS依赖库

1.安装libevent依赖

解压libevent源码包:tar -zxvf libevent-2.1.11-stable.tar.gz

进入源码目录:cd libevent-2.1.11-stable

编译安装前配置:./configure 

编译安装:make && make install

默认安装位置:/usr/local/lib

2.安装libfasttcommon依赖

解压libfasttcommon源码包:tar -zxvf libfastcommon-1.0.41.tar.gz

进入源码目录:cd libfastcommon-1.0.41

编译安装:./make.sh && ./make.sh install

默认安装位置:/usr/lib64

六、安装部署Tracker服务和Storage服务

1.安装fastdfs服务

解压fastdfs源码包:tar -zxvf fastdfs-6.01.tar.gz

进入fastdfs源码包:cd fastdfs-6.01

编译安装:./make.sh && ./make.sh install

2.fastdfs服务目录信息

安装完成后服务及脚本拷贝到/usr/bin 目录,配置文件拷贝到/etc/fdfs目录,启动脚本拷贝到/etc/init.d/目录

3.注册开机启动

chkconfig --add fdfs_trackerd

chkconfig fdfs_trackerd on

chkconfig --add fdfs_storaged

chkconfig fdfs_storaged on

4.数据目录规划

创建fdfs数据主目录:mkdir /work/fdfs

创建tracker数据目录:mkdir /work/fdfs/tracker

创建storage数据目录:mkdir /work/fdfs/storage

5.配置tracker服务

将/etc/fdfs目录下的tracker.conf.sample改为tracker.conf:mv tracker.conf.sample  tracker.conf修改内容如下:

将base_path=/home/yuqing/fastdfs 改为:/work/fdfs/tracker(该目录为上面定义创建)

启动Tracker服务:systemctl start fdfs_trackerd

6.配置storage服务

将/etc/fdfs目录下的storage.conf.sample改为storage.conf:mv storage.conf.sample storage.conf修改内容如下:

base_path=/home/yuqing/fastdfs 改为:base_path=/work/fdfs/storage(该目录为上面定义创建)

store_path0=/home/yuqing/fastdfs 改为:store_path0=/work/fdfs/storage(该目录为上面定义创建)

tracker_server=192.168.209.121:22122 改为:tracker_server=192.168.100.111:22122和tracker_server=192.168.100.112:22122

将/etc/fdfs/torage_ids.conf.sample 为storage_ids.conf,内容修改为当前group的storage节点信息:

100001    group1    192.168.100.111

100002    group1    192.168.100.112

启动Storage服务:systemctl start fdfs_storaged

七、Nginx服务安装配置

1.下载Nginx源码包

官网地址:http://nginx.org/

下载地址:http://nginx.org/en/download.html

2.上传并解压Nginx源码包及fastdfs插件包

tar -zxvf nginx-1.16.1.tar.gz

tar -zxvf fastdfs-nginx-module-1.21.tar.gz

3.编译Nginx准备

进入解压目录:cd nginx-1.16.1

拷贝fastdfs插件包到nginx源码目录:mv ../fastdfs-nginx-module-1.21 .

执行编译准备:./configure --prefix=/work/nginx \--with-stream \--add-module=fastdfs-nginx-module-1.21/src

注意:一定要有gcc和openssl编译相关的依赖

4.编译安装Nginx

make && make install

5.注册到系统服务

vi /usr/lib/systemd/system/nginx.service

[Unit]
Description=nginx
Documentation=http://nginx.org/en/docs/
After=network.target

[Service]
Type=forking
PIDFile=/work/nginx/logs/nginx.pid
ExecStartPre=/work/nginx/sbin/nginx -t -c /work/nginx/conf/nginx.conf
ExecStart=/work/nginx/sbin/nginx -c /work/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

6.设置Nginx开机启动项

systemctl enable nginx

然后就能使用systemctl start/stop/status nginx管理nginx了

7.修改Nginx配置

vi /work/nginx/conf/nginx.conf

#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;
}


stream {

    upstream tracker {
         server 192.168.100.111:22122 weight=1 max_fails=2 fail_timeout=10s;
         server 192.168.100.112:22122 weight=1 max_fails=2 fail_timeout=10s;
    }


    server {
        listen       7777;
        proxy_timeout 5m;
        proxy_pass tracker;
        proxy_connect_timeout 10s;
    }


}


http {

    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;


    upstream storage {
         server 192.168.100.111:8888 weight=1 max_fails=2 fail_timeout=10s;
         server 192.168.100.112:8888 weight=1 max_fails=2 fail_timeout=10s;
    }


    server {
        listen       80;
        server_name  localhost;
        
        location /group1 {
            proxy_pass         http://storage;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
        
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }


    server {
        listen       8888;
        server_name  localhost;

        location / {
            alias /work/fdfs/storage/data/;
            ngx_fastdfs_module;
        }
    }

}

8.配置nginx的fdfs插件

将/etc/fdfs下的http.conf.sample和mime.types.sample重命名为:http.conf和mime.types

将fastdfs-nginx-module-1.21/src下的mod_fastdfs.conf拷贝到/etc/fdfs下

修改mod_fastdfs.conf如下:

连接超时时间: connect_timeout=5

Tracker服务地址:tracker_server=192.168.100.111:22122  和tracker_server=192.168.100.112:22122

Storage服务端口:storage_server_port=23000

如果文件ID的uri中包含/group**,则要设置为true:url_have_group_name = true

Storage配置的store_path0路径,必须和storage.conf中的一致:store_path0=/work/fdfs/storage

其他详细配置如下:

# connect timeout in seconds
# default value is 30s
connect_timeout=5

# network recv and send timeout in seconds
# default value is 30s
network_timeout=10

# the base path to store log files
base_path=/work/fdfs/storage

# if load FastDFS parameters from tracker server
# since V1.12
# default value is false
load_fdfs_parameters_from_tracker=true

# storage sync file max delay seconds
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V1.12
# default value is 86400 seconds (one day)
storage_sync_file_max_delay = 86400

# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V1.13
use_storage_id = false

# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V1.13
storage_ids_filename = storage_ids.conf

# FastDFS tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
# valid only when load_fdfs_parameters_from_tracker is true
tracker_server=192.168.100.111:22122
tracker_server=192.168.100.112:22122


# the port of the local storage server
# the default value is 23000
storage_server_port=23000

# the group name of the local storage server
group_name=group1

# if the url / uri including the group name
# set to false when uri like /M00/00/00/xxx
# set to true when uri like ${group_name}/M00/00/00/xxx, such as group1/M00/xxx
# default value is false
url_have_group_name = true

# path(disk or mount point) count, default value is 1
# must same as storage.conf
store_path_count=1

# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
# must same as storage.conf
store_path0=/work/fdfs/storage

# standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# set the log filename, such as /usr/local/apache2/logs/mod_fastdfs.log
# empty for output to stderr (apache and nginx error_log file)
log_filename=

# response mode when the file not exist in the local file system
## proxy: get the content from other storage server, then send to client
## redirect: redirect to the original storage server (HTTP Header is Location)
response_mode=proxy

# the NIC alias prefix, such as eth in Linux, you can see it by ifconfig -a
# multi aliases split by comma. empty value means auto set by OS type
# this paramter used to get all ip address of the local host
# default values is empty
if_alias_prefix=

# use "#include" directive to include HTTP config file
# NOTE: #include is an include directive, do NOT remove the # before include
#include http.conf


# if support flv
# default value is false
# since v1.15
flv_support = true

# flv file extension name
# default value is flv
# since v1.15
flv_extension = flv


# set the group count
# set to none zero to support multi-group on this storage server
# set to 0  for single group only
# groups settings section as [group1], [group2], ..., [groupN]
# default value is 0
# since v1.14
group_count = 1

# group settings for group #1
# since v1.14
# when support multi-group on this storage server, uncomment following section
[group1]
group_name=group1
storage_server_port=23000
store_path_count=1
store_path0=/work/fdfs/storage

# group settings for group #2
# since v1.14
# when support multi-group, uncomment following section as neccessary
#[group2]
#group_name=group2
#storage_server_port=23000
#store_path_count=1
#store_path0=/home/yuqing/fastdfs

八、服务启动及验证

分别启动keepalive、nginx、tracker、storage服务

查看服务是否正常服务:

在任意Storage机器上查看集群状态:fdfs_monitor /etc/fdfs/storage.conf

九、Java客户端测试

1.java项目Maven依赖

项目地址:https://github.com/tobato/FastDFS_Client

目前客户端主要依赖于SpringBoot,因此必须引入:
<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.0.0.RELEASE</version>
   <relativePath/>
</parent>

FastDFS 依赖包:
<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.26.7</version>
</dependency>

将FastDFS引入项目:
@Import(FdfsClientConfig.class)

在application.yml当中配置Fdfs相关参数:
fdfs:
  pool:
    #连接池最大数量
    max-total: 200
    #每个tracker地址的最大连接数
    max-total-per-key: 50
    #连接耗尽时等待获取连接的最大毫秒数
    max-wait-millis: 5000
  so-timeout: 1500
  connect-timeout: 600
  thumb-image:
    width: 150
    height: 150
  tracker-list:
    - 192.168.100.110:7777
或者
fdfs:
  pool:
    #连接池最大数量
    max-total: 200
    #每个tracker地址的最大连接数
    max-total-per-key: 50
    #连接耗尽时等待获取连接的最大毫秒数
    max-wait-millis: 5000
  so-timeout: 1500
  connect-timeout: 600
  thumb-image:
    width: 150
    height: 150
  tracker-list:
    - 192.168.100.111:22122
    - 192.168.100.112:22122

使用接口服务对Fdfs服务端进行操作,主要接口包括:
TrackerClient - TrackerServer接口
GenerateStorageClient - 一般文件存储接口 (StorageServer接口)
FastFileStorageClient - 为方便项目开发集成的简单接口(StorageServer接口)
AppendFileStorageClient - 支持文件续传操作的接口 (StorageServer接口)

2.代码测试

package com.maxbill;

import com.github.tobato.fastdfs.FdfsClientConfig;
import com.github.tobato.fastdfs.domain.fdfs.MetaData;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileInputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Log4j2
@Component
@Import(FdfsClientConfig.class)
public class FdfsClientUtil {

    private static final String BASE_URL = "http://192.168.100.110:8888/";

    @Autowired
    private FastFileStorageClient storageClient;

    private static FdfsClientUtil fdfsClientUtil;

    @PostConstruct
    public void init() {
        fdfsClientUtil = this;
    }


    /**
     * 文件上传
     *
     * @param file    文件信息
     * @param infoMap 文件扩展信息
     * @return 上传路径
     */
    public static Map<String, Object> uploadFile(File file, Map<String, String> infoMap) {
        try {
            String fileName = file.getName();
            String fileType = fileName.substring(fileName.lastIndexOf("\\") + 1);
            //String fileType = FilenameUtils.getExtension(file.getName())
            log.info("[fdfs-upload]-start upload file ... ");
            log.info("[fdfs-upload]-request upload file name: {}", fileName);
            log.info("[fdfs-upload]-request upload file info: {}", infoMap);
            StorePath path = fdfsClientUtil.storageClient.uploadFile(new FileInputStream(file), file.length(), fileType, getMetaData(infoMap));
            log.info("[fdfs-upload]-upload success path: {}", path.getFullPath());
            return getResultMap(BASE_URL.concat(path.getFullPath()), null);
        } catch (Exception e) {
            log.error("[fdfs-upload]-upload file exception info: {}", e.getMessage());
            return getResultMap(null, e.getMessage());
        }
    }


    /**
     * 下载文件
     *
     * @param filePath 文件路径标识
     * @return 文件字节
     */
    public static Map<String, Object> downloadFile(String filePath) {
        try {
            filePath = filePath.replace(BASE_URL, "");
            StorePath storePath = StorePath.parseFromUrl(filePath);
            String group = storePath.getGroup();
            String path = storePath.getPath();
            log.info("[fdfs-download]-start download file ... ");
            log.info("[fdfs-download]-request download file group: {}", group);
            log.info("[fdfs-download]-request download file path: {}", path);
            byte[] data = fdfsClientUtil.storageClient.downloadFile(group, path, new DownloadByteArray());
            log.info("[fdfs-download]-request download file success ... ");
            return getResultMap(data, null);
        } catch (Exception e) {
            log.error("[fdfs-download]-download file exception info: {}", e.getMessage());
            return getResultMap(null, e.getMessage());
        }
    }

    /**
     * 删除文件
     *
     * @param filePath 文件路径标识
     * @return 操作结果
     */
    public static boolean deleteFile(String filePath) {
        try {
            filePath = filePath.replace(BASE_URL, "");
            StorePath storePath = StorePath.parseFromUrl(filePath);
            String group = storePath.getGroup();
            String path = storePath.getPath();
            log.info("[fdfs-delete]-start delete file ... ");
            log.info("[fdfs-delete]-request delete file group: {}", group);
            log.info("[fdfs-delete]-request delete file path: {}", path);
            fdfsClientUtil.storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
            log.info("[fdfs-delete]-request delete file success ... ");
            return true;
        } catch (Exception e) {
            log.error("[fdfs-delete]-delete file exception info: {}", e.getMessage());
            return false;
        }
    }


    /**
     * 查看文件元信息
     *
     * @param filePath 文件路径标识
     * @return 文件信息
     */
    public static Map<String, Object> getFileInfo(String filePath) {
        try {
            filePath = filePath.replace(BASE_URL, "");
            StorePath storePath = StorePath.parseFromUrl(filePath);
            String group = storePath.getGroup();
            String path = storePath.getPath();
            log.info("[fdfs-meta]-start meta file ... ");
            log.info("[fdfs-meta]-request meta file group: {}", group);
            log.info("[fdfs-meta]-request meta file path: {}", path);
            Map<String, String> infoMap = new HashMap<>();
            infoMap.put("createPath", filePath);
            Set<MetaData> metaData = fdfsClientUtil.storageClient.getMetadata(storePath.getGroup(), storePath.getPath());
            log.info("[fdfs-meta]-request meta file success ... ");
            if (null != metaData && !metaData.isEmpty()) {
                metaData.forEach(meta -> {
                    infoMap.put(meta.getName(), meta.getValue());
                });
            }
            return getResultMap(infoMap, null);
        } catch (Exception e) {
            log.error("[fdfs-meta]-meta file exception info: {}", e.getMessage());
            return getResultMap(null, e.getMessage());
        }
    }


    /**
     * 封装附件元信息
     *
     * @param infoMap 自定义数据
     * @return 附件元信息
     */
    private static Set<MetaData> getMetaData(Map<String, String> infoMap) {
        if (null != infoMap && !infoMap.isEmpty()) {
            Set<MetaData> metaDataSet = new HashSet<>();
            for (String key : infoMap.keySet()) {
                metaDataSet.add(new MetaData(key, infoMap.get(key)));
            }
            return metaDataSet;
        } else {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Set<MetaData> metaDataSet = new HashSet<>();
            metaDataSet.add(new MetaData("createUser", "MaxBill"));
            metaDataSet.add(new MetaData("createDate", df.format(new Date())));
            return metaDataSet;
        }
    }

    /**
     * 封装结果信息
     *
     * @param data 数据
     * @param info 信息
     * @return 操作结果
     */
    private static Map<String, Object> getResultMap(Object data, String info) {
        Map<String, Object> resultMap = new HashMap<>();
        if (StringUtils.isEmpty(info)) {
            resultMap.put("flag", true);
            resultMap.put("data", data);
            resultMap.put("info", "success");
        } else {
            resultMap.put("flag", false);
            resultMap.put("info", info);
            resultMap.put("data", null);
        }
        return resultMap;
    }


}

 

© 著作权归作者所有

MaxBill

MaxBill

粉丝 67
博文 89
码字总数 78950
作品 1
宝山
后端工程师
私信 提问
加载中

评论(14)

晒太阳的小猪
晒太阳的小猪
自由最终演进出了市场
LeoRmAo
LeoRmAo
能直接读文件吗?还是必须要下载
MaxBill
MaxBill 博主
图片文件 在src标签中是直接显示的,也可以下载下来
z
zhangleijie
mino
王小杆
王小杆
有个地方不太理解,nginx装在了哪几台机器上?我觉着都装在了tracker上?但看nginx配置里配置了alias /work/fdfs/storage/data/;有些疑惑。
MaxBill
MaxBill 博主
nginx装在有storage的机器上,tracker上有是因为本文就用来两台机器,装在一起了,实际生产环境上一般是分开的,解决文件访问代理和group node之间问阿金未及时的问题, /work/fdfs/storage/data/这个是strfoage上实际文件上传后存在的路径
王小杆
王小杆
感谢,理解了。
Yoona520
Yoona520
Hadoop
MaxBill
MaxBill 博主
hadoop 适用于大文件存储,fdfs适用于小文件存储场景
稀饭00
稀饭00
这东西停更很多年了,还在用吗,有没有可以替代的
zjg23
zjg23
博主用的6.01版本好像是最近才发布的版本
MaxBill
MaxBill 博主
没有停更呀,我测试用的就是最新的
稀饭00
稀饭00
0.0真的吗,我阿里都停止维护了哒,我去看看呢
s_jqzhang
s_jqzhang
Go-fast dfs
FastDFS服务器集群部署和集成客户端到SpringBoot

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题,同时也能做到在集群环...

maoqitian
2018/11/01
0
0
FastDFS安装、配置、部署(一)

http://minglisoft.cn/technology声明:对于分布式的一些技术点在网上都可以查到,这边对于一些基本的操作做了些相关的总结,并作为分布式框架技术的支持文档,希望可以帮助到大家 FastDFS是...

qq58edeba279279
2018/06/26
0
0
FastDFS的配置、部署与API使用解读(7)Nginx的FastDFS模块

转载请注明来自“诗商·柳惊鸿 Poechant 的CSDN博客”。 原文地址:FastDFS的配置、部署与API使用解读(7)Nginx的FastDFS模块 1、Nginx的FastDFS模块什么作用? 我们在使用FastDFS部署一个分...

晨曦之光
2012/04/24
1K
0
Docker安装FastDFS

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010775025/article/details/85777774 什么是FastDFS? FastDFS 是用 c 语言编写的一款开源的分布式文件系统。...

心诚则灵--艾
01/04
0
0
CentOS7下分布式文件系统FastDFS的安装 配置 (单节点)

背景 FastDFS是一个开源的轻量级分布式文件系统,为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,解决了大容量存储和负载均衡的问题,特别适...

botaozhao
2018/04/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用zabbix自带的模板监控MySQL自带

一、安装zabbix server 略 二、安装zabbix agent 略 三、给主机套自带的模板 略 四、创建授权用户 mysql> grant all on *.* to 'zabbix'@'localhost' identified by 'musingtec2019';Quer......

雁南飞丶
10分钟前
4
0
notepad++快捷键

notepad++也情有独钟,最近发现了一个快捷键,就是选中单词,ctrl+shift+enter。不过现在想知道一个快捷键,假设有三行代码,选中后一般按TAB就可以三行全部缩进. Notepad++绝对是windows下进...

zhengzhixiang
31分钟前
5
0
区块链背景是什么?区块链的意义是什么?

一、前言 区块链技术的首次也是最著名的应用是比特币,一个在2009年1月初正式上线运行的去中心化数字货币应用,他的创始人叫中本聪,但目前大家并不知道此人的真实身份。 比特币不同于现代国...

daxiongdi
36分钟前
4
0
在Bash中循环浏览文件内容

如何使用Bash遍历文本文件的每一行? 使用此脚本: echo "Start!"for p in (peptides.txt)do echo "${p}"done 我在屏幕上得到以下输出: Start!./runPep.sh: line 3: syntax error......

技术盛宴
39分钟前
8
0
史上最强IP正则表达式

port ([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-4]\\d{4}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5]) ipv4 ^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$ ipv4+mask......

蜗牛伊
42分钟前
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部