【CentOS7】:配置FastDFS分布式服务器并整合springboot进行上传接口测试(单机版)

前言

请添加图片描述

简介

可 以 跳 过 简 介 部 分 , 直 接 跳 至 安 装 步 骤 \color{red}{可以跳过简介部分,直接跳至安装步骤}

1. 介绍

技术论坛:http://bbs.chinaunix.net/forum-240-1.html
资源地址:https://sourceforge.net/projects/fastdfs/
源码资源:https://github.com/happyflsh100 注,该链接或许失效了

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

粗略介绍,具体可参考百度百科:链接

2. 术语介绍

  • TrackerServer:跟踪服务器,主要做调度工作,在访问上起负载均衡的作用,记录storage Server的状态
  • StorageServer:存储服务器,文件盒meta data都保存到存储服务器上
  • group:组,也称为卷(等同于window上的C盘)。同组内服务器上的文件是完全相同的
  • 文件标识:包括两部分:组名和文件名(包含路径)
  • meta data:文件相关属性,键值对(key value pair)方式,如:width=1024,height=768

3. 同步机制

同一组内的storage Server之间是对等的,文件上传,删除等操作可以在任意一台storage Server 上进行;

文件同步只在同组内的storage Server之间进行,采用push方式,即源服务器同步给目标服务器;

源头数据才需要同步,备份数据不需要再次同步,否则就构成环路了;

上述第二条规则有个例外,就是新增一台storage Server时,由已有的一台storage Server将已有的所有数据(包括源头数据和备份数据)同步给该新增服务器

4. FastDFS运行时目录结构

4.1 Tracker Server目录


${base_path}
   
|__data
   
|     |__storage_groups.dat:存储分组信息
   
|     |__storage_servers.dat:存储服务器列表
   
|__logs
         
   |__trackerd.log:tracker server日志文件

4.2 storageServer目录
${base_path}
   
|__data
   
|     |__.data_init_flag:当前storage server 初始化信息
   
|     |__storage_stat.dat:当前storage server统计信息
   
|     |__sync:存放数据同步相关文件
   
|     |     |__binlog.index:当前的binlog文件索引号
   
|     |     |__binlog.###:存放更新操作记录(日志)
   
|     |     |__${ip_addr}_${port}.mark:存放同步的完成情况
   
|     |
   
|     |__一级目录:256个存放数据文件的目录,如:00, 1F
   
|           |__二级目录:256个存放数据文件的目录
   
|__logs
       
   |__storaged.log:storage server日志文件

5. 同其它文件存储的简单对比

5.1 FastDFS和集中存储方式对比

指标 FastDFS NFS 集中存储设备如:NetApp、NAS
线性扩容性
文件高并发访问性能
文件访问方式 专用API POSIX POSIX
硬件成本 较低 中等
相同内文件只保存一份 支持 不支持 不支持

5.2 FastDFS和mogileFS对比

指标 FastDFS mogileFS
系统简洁性 简洁 只有两个角色:tracker和storage 一般 有三个角色:tracker、storage 和存储文件信息的mysql db
系统性能 很高(没有使用数据库,文件同步直接点对点,不经过tracker中转) 高(是哟给你mysql来存储文件索引信息,文件同步通过tracker调度和中转)
系统稳定性 高(C语言开发,可以支持高并发和高负载) 一般(peri语言开发,高并发和高负载支持一般)
RAID方式 分组(组内冗余),灵活性大 动态冗余,灵活性一般
通讯协议 专用协议,下载文件支持HTTP HTTP
技术文档 较详细 较少
文件附加属性 meta data 支持 支持
相同内容文件支保存一份 支持 不支持
下载文件支持文件偏移量 支持 不支持

安装FastDFS

1. 下载所需的安装包并上传到服务器上

下载链接
请添加图片描述

2. 安装各种所需工具命令包/依赖

2.1 安装GCC依赖

编译器

sudo yum -y install gcc

2.2 安装unzip工具

unzip工具可以帮我们对压缩包进行解压

sudo yum install -y unzip zip

2.3 安装libevent

sudo yum -y install libevent
  • 或许会出现以下问题,不过可以不用理会,具体原因没有深究,不过不影响
    请添加图片描述

2.3 安装Nginx所需依赖

sudo yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel

2.4 安装libfastcommon-master

  • 这个没有yum包,只能通过解压安装
  • 解压上传的libfastcommon-master.zip
tar -xvf libfastcommon-master.zip
  • 若上述命令不生效,则使用如下命令
unzip libfastcommon-master.zip
  • 进入解压完成的目录中
cd libfastcommon-master
  • 编译并且安装
sudo ./make.sh 
sudo ./makesh install

目前为止,依赖已安装完毕,接下来安装FastDFS >>>

3. 安装FastDFS

3.1 编译安装

  • 解压
tar -xvf FastDFS_v5.08.tar.gz
  • 进入目录
cd FastDFS
  • 编译并安装
sudo ./make.sh 
sudo ./make.sh install
  • 校验安装结果
  1. 安装完成,我们应该能在/etc/init.d/目录,通过命令ll /etc/init.d/ | grep fdfs看到FastDFS提供的启动脚本:
    请添加图片描述
    其中:
  • fdfs_trackerd 是tracker启动脚本
  • fdfs_storaged 是storage启动脚本
  1. 我们可以在 /etc/fdfs目录,通过命令查看到以下配置文件模板:
    请添加图片描述
    其中:
  • tarcker.conf.sample 是tracker的配置文件模板
  • storage.conf.sample 是storage的配置文件模板
  • client.conf.sample 是客户端的配置文件模板

3.2 启动tracker

FastDFS的tracker和storage在刚刚的安装过程中,都已经被安装了,因此我们安装这两种角色的方式是一样的。不同的是,两种需要不同的配置文件。

要启动tracker,就修改刚刚看到的tarcker.conf,并且启动fdfs_trackerd脚本即可。

  • 编辑tracker配置
    首先将模板文件进行复制和重命名:
sudo cp tracker.conf.sample tracker.conf
sudo vim tracker.conf

打开tracker.conf,修改base_path配置:

base_path=/leyou/fdfs/tracker # tracker的数据和日志存放目录
  • 创建目录
    刚配置的目录不可能存在,需要创建
sudo mkdir -p /leyou/fdfs/tracker
  • 启动tracker
    我们可以使用 sh /etc/init.d/fdfs_trackerd 启动,不过安装过程中,fdfs已经被设置为系统服务,我们可以采用熟悉的服务启动方式:
sudo service fdfs_trackerd start # 启动fdfs_trackerd服务,停止用stop

请添加图片描述

另外,我们可以通过以下命令,设置tracker开机启动:

sudo chkconfig fdfs_trackerd on

3.2 启动storage

要启动tracker,就修改刚刚看到的storage.conf,并且启动fdfs_storage脚本即可。

  • 编辑storage配置
    首先我们将模板文件进行赋值和重命名:
sudo cp storage.conf.sample storage.conf
sudo vim storage.conf

打开storage.conf,修改base_path配置:

base_path=/leyou/fdfs/storage # storage的数据和日志存放目录
store_path0=/leyou/fdfs/storage # storage的上传文件存放路径
tracker_server=192.168.xxx.xxx:22122 # tracker的地址, 该ip是服务器ip地址,端口可随意命名
  • 创建目录
sudo mkdir -p /leyou/fdfs/storage
  • 启动storage
    我们可以使用 sh /etc/init.d/fdfs_storaged 启动,同样我们可以用服务启动方式:
sudo service fdfs_storaged start  # 启动fdfs_storaged服务,停止用stop

请添加图片描述

另外,我们可以通过以下命令,设置tracker开机启动:

sudo chkconfig fdfs_storaged on

最后,通过ps -ef | grep fdfs 查看进程:
请添加图片描述

3.3 还需要更改一处配置(client.conf)

  • 模板文件进行赋值和重命名:
sudo cp client.conf.sample client.conf
sudo vim client.conf
  • 打开client.conf,修改配置:
base_path=/leyou/fdfs/storage # storage的数据和日志存放目录
store_path0=/leyou/fdfs/storage # storage的上传文件存放路径
tracker_server=192.168.xxx.xxx:22122 # tracker的地址, 该ip是服务器ip地址,端口可随意命名

4. 安装Nginx及FastDFS模块

4.1 FastDFS的Nginx模块

  • 解压
tar -xvf fastdfs-nginx-module_v1.16.tar.gz
  • 配置config文件
# 进入配置目录
cd /home/leyou/fdfs/fastdfs-nginx-module/src/
# 修改配置
vim config
# 执行下面命令(将配置中的/usr/local改为/usr):
:%s+/usr/local/+/usr/+g
  • 配置mod_fastdfs.conf
# 将src目录下的mod_fastdfs.conf复制到 /etc/fdfs目录:
sudo cp mod_fastdfs.conf /etc/fdfs/
# 编辑该文件
sudo vim /etc/fdfs/mod_fastdfs.cof
  • 修改一下配置:
connect_timeout=10                  		# 客户端访问文件连接超时时长(单位:秒)
tracker_server=192.168.xxx.xxx:22122  	# tracker服务IP和端口
url_have_group_name=true            		# 访问链接前缀加上组名
store_path0=/leyou/fdfs/storage        		# 文件存储路径
  • 复制 FastDFS的部分配置文件到/etc/fdfs目录
cd /home/leyou/fdfs/FastDFS/conf/
cp http.conf mime.types /etc/fdfs/

4.2 安装Nginx

  • 解压
tar -xvf nginx-1.10.0.tar.gz
  • 配置
sudo ./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/home/leyou/fdfs/fastdfs-nginx-module/src
  • 编译安装
sudo make && sudo make install
  • 配置nginx整合fastdfs-module模块
    我们需要修改nginx配置文件,在/opt/nginx/config/nginx.conf文件中:
sudo vim  /opt/nginx/conf/nginx.conf
  • 将文件中,原来的server 80{ ...}部分代码替换为如下代码:
server {
    
    
        listen       80;
        server_name  image.taotao.com;

    	# 监听域名中带有group的,交给FastDFS模块处理
        location ~/group([0-9])/ {
    
    
            ngx_fastdfs_module;
        }

        location / {
    
    
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
    
    
            root   html;
        }
        
    }
  • 启动
nginx # 启动
nginx -s stop # 停止
nginx -s reload # 重新加载配置
  • 设置nginx开机启动(非必要)
    创建一个开机启动的脚本:
vim /etc/init.d/nginx

添加以下内容:

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  NGINX is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/bin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/opt/nginx/conf/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

make_dirs() {
    
    
   # make required directories
   user=`$nginx -V 2>&1 | grep "configure arguments:.*--user=" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   if [ -n "$user" ]; then
      if [ -z "`grep $user /etc/passwd`" ]; then
         useradd -M -s /bin/nologin $user
      fi
      options=`$nginx -V 2>&1 | grep 'configure arguments:'`
      for opt in $options; do
          if [ `echo $opt | grep '.*-temp-path'` ]; then
              value=`echo $opt | cut -d "=" -f 2`
              if [ ! -d "$value" ]; then
                  # echo "creating" $value
                  mkdir -p $value && chown -R $user $value
              fi
          fi
       done
    fi
}

start() {
    
    
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    
    
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    
    
    configtest || return $?
    stop
    sleep 1
    start
}

reload() {
    
    
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    
    
    restart
}

configtest() {
    
    
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    
    
    status $prog
}

rh_status_q() {
    
    
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac
  • 修改文件权限,并加入服务列表
# 修改权限
chmod 777 /etc/init.d/nginx 
# 添加到服务列表
chkconfig --add /etc/init.d/nginx 
  • 设置开机启动
chkconfig nginx on

5. 测试

5.1 基于服务器上测试

/usr/bin/fdfs_test /etc/fdfs/client.conf  upload /home/logo.jpg

5.2 springboot进行测试

创建springboot项目,百度

  • 引入jar包
<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.26.1-RELEASE</version>
</dependency>
  • 配置文件
fdfs:
  connect-timeout: 600
  so-timeout: 2500
  thumb-image:
    height: 60
    width: 60
  tracker-list:
    - 192.168.xxx.xxx:22122
  • 配置类
@Configuration
@Import(FdfsClientConfig.class)
// 解决jmx重复注册bean的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastdfsImporter {
    
    
    // 导入依赖组件
}
  • 上传接口
@PostMapping("image")
    public String uploadImage(@RequestParam("file") MultipartFile file) {
    
    

        //保存图片
        try {
    
    
            String extensionName = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
            StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), extensionName, null);
            //返回保存图片的完整url
            return storePath.getFullPath();
        } catch (IOException e) {
    
    
            throw new RuntimeException();
        }
    }
  • 成功后返回:
    请添加图片描述
  • 生成文件名
    当文件存储到某个子目录后,即认为该文件存储成功,接下来会为给该文件生成一个文件名,文件名由group名称/存储目录/两级目录/file_id.后缀名 拼接而成。
  • group组名/卷名。文件上传成功以后所在的storage组名称,由storage服务返回。
  • M00虚拟磁盘路径。与storage配置文件中磁盘选项store_path*对应。如果配置了storage_path0则是M00,如果配置了store_path1则是M01,以此类推。比如:store_path = /fastdfs/storage/storeM00则表示:/fastdfs/storage/store/data
  • /00/00数据两级目录。storage服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。
  • .jpg的前缀:file_id,由storage server IP、文件创建时间、文件大小、文件crc32和一个随记数组成,然后将这个二进制串进行base64编码,转换为字符串。
  • 返回的这一串数字就是文件名

6. 问题

6.1 本地上传测试不成功如图

请添加图片描述

  • 修改/etc/fdfs/client.conf配置文件,查看3.4

6.2 查看nginx是否安装成功

请添加图片描述

6.3 本地上使用访问虚拟机上图片,成功后

请添加图片描述

6.4 如不能访问,或连接不上,测试需要开放端口或关闭防火墙,如:22122,80,23000

  • 命令
# 查看防火墙状态
systemctl status firewalld
# 关闭防火墙
systemctl firewalld stop
# 对外开放某个端口
firewall-cmd --zone=public --add-port=80/tcp --permanent

参考资料

防火墙命令文章
FastDFS+阿里OOS文章
网路上的项目

猜你喜欢

转载自blog.csdn.net/weixin_45511500/article/details/120437396