FastDFS实现上传文件(在Linux下安装与使用的详细步骤)

一. Linux下FastDFS的安装

  1. 下载
    https://github.com/happyfish100/FastDFS
    https://github.com/happyfish100/libfastcommon
    https://github.com/happyfish100/fastdfs-nginx-module
    fastdfs-5.11.tar.gz
    libfastcommon-1.0.39.tar.gz
    fastdfs-nginx-module-1.20.tar.gz

  2. 上传
    在这里插入图片描述
    将下载的3个包上传

  3. 安装依赖
    GCC libevent Nginx所需依赖
    yum install -y gcc
    yum install -y libevent
    yum install -y pcre pcre-devel zlib zlib-devel openssl openssl-devel

  4. 安装libfastcommon (需要先安装它再安装fastdfs)
    tar -xvf libfastcommon-1.0.39.tar.gz
    cd libfastcommon-1.0.39/
    ./make.sh && ./make.sh install

  5. 同理,解压和编译安装一下fastdfs。

  6. 装完后可以看到tracker和storage的可执行脚本
    ll /etc/init.d/ | grep fdfs
    在这里插入图片描述

  7. 修改配置文件,默认在/etc/fdfs/
    FastDFS实现上传文件(在Linux下安装与使用的详细步骤)_第1张图片
    先把配置文件名中的sample去了。
    然后修改tracker的存放数据和日志的目录。
    并创建该目录:mkdir -p 加上路径
    在这里插入图片描述

  8. 启动tracker
    在这里插入图片描述
    开机启动:chkconfig fdfs_trackerd on

  9. 同理,修改storage的配置文件:

  • 修改storage存储数据和日志的目录bath_path :base_path=/home/learn/fastdfs/storage

  • 修改上传文件存储的目录store_path0:store_path0=/home/learn/fastdfs/storage

  • 配置tracker的地址:tracker_server=192.168.58.129:22122

  • 创建配置的目录文件夹。

  • 启动:service fdfs_storaged start

二. Linux下Nginx及与FastDFS集成模块的安装

2.1 FastDFS的Nginx模块

在这里插入图片描述

  1. 解压:tar -xvf fastdfs-nginx-module-1.20.tar.gz

  2. 进入到解压后的目录下的src,修改config:
    执行下面命令(将配置中的/usr/local改为/usr)
    :%s+/usr/local/+/usr/+g

  3. 将mod_fastdfs.conf移动至fdfs运行的配置文件目录下
    cp mod_fastdfs.conf /etc/fdfs/
    并修改:

  • connect_timeout 超时时间选择修改
  • tracker_server=192.168.58.129:22122
  • url_have_group_name = true url中需要group组名
  • store_path0=/home/learn/fastdfs/storage 之前配置的存储目录
  1. 进入到之前解压好的fastdfs目录下,将其conf下的http.conf、mime.conf移动至/etc/fdfs
    FastDFS实现上传文件(在Linux下安装与使用的详细步骤)_第2张图片
    cp http.conf mime.types /etc/fdfs/

2.2 安装Nginx

  1. 配置:
    ./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/home/orcas/software/fastdfs/fastdfs-nginx-module-1.20/src
    编译安装:
    make && make install

  2. 然而它报错:
    /usr/include/fastdfs/fdfs_define.h:15:27: fatal error: common_define.h: No such file or directory #include "common_define.h"
    通过 http://blog.opstest.cn/?p=741 该文章解决问题。
    修改fastdfs-nginx-module-1.20/src/config文件,修改如下:
    ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
    CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
    再重新执行 配置、编译、安装。

  3. PS:如果之前已安装好nginx,就配置再编译,不用安装。
    将nginx-1.12.2目录下的objs下的nginx脚本替换 /usr/bin/nginx

  4. 修改nginx配置
    cd /opt/nginx/conf
    vim nginx.conf
    FastDFS实现上传文件(在Linux下安装与使用的详细步骤)_第3张图片

2.3 Nginx开机启动脚本

vim /etc/init.d/nginx
添加如下内容:
(注意两点:
nginx="/usr/bin/nginx"NGINX_CONF_FILE="/opt/nginx/conf/nginx.conf"
要与之前配置的路径相同)

#!/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

(本地hosts添加域名解析)

三.上传文件至FastDFS

1、先便捷测试一下
同样修改client.conf配置文件中的base_path和tracker_server
在创建的那个目录中放一张图
然后上传,成功会返回文件id
在这里插入图片描述
group1/M00/00/00/wKg6gVw7FhqAWsRWAAKgjAHcRjA150.jpg
group1是group_name配置的组名
M00 是store_path0 (store_path1就是M01)

可以在之前配置的storage存储上传文件的目录下找到该图
FastDFS实现上传文件(在Linux下安装与使用的详细步骤)_第4张图片

在浏览器中也可以访问:
FastDFS实现上传文件(在Linux下安装与使用的详细步骤)_第5张图片


2、使用fastdfs的java客户端
依赖:

        <dependency>
            <groupId>net.oschina.zcx7878groupId>
            <artifactId>fastdfs-client-javaartifactId>
        dependency>

配置:

fastdfs:
    connect_timeout_in_seconds: 5
    network_timeout_in_seconds: 30
    charset: UTF-8
    tracker_servers: 192.168.58.129:22122 #多个 trackerServer中间以逗号分隔

代码参考:

    @Value("${fastdfs.tracker_servers}")
    private String tracker_servers;

    @Value("${fastdfs.connect_timeout_in_seconds}")
    private int connect_timeout;

    @Value("${fastdfs.network_timeout_in_seconds}")
    private int network_timeout;

    @Value("${fastdfs.charset}")
    private String charset;

	@Override
    public UploadFileResult upload(MultipartFile multipartFile) {
        if (multipartFile == null) {
            ExceptionCast.cast(FileSystemCode.FS_UPLOADFILE_FILE_IS_NULL);
        }
        // 上传至fastDFS, 返回文件id
        String fileId = this.fdfsUpload(multipartFile);
        if (StringUtils.isEmpty(fileId)) {
            ExceptionCast.cast(FileSystemCode.FS_UPLOADFILE_SERVER_FAIL);
        }
        return new UploadFileResult(CommonCode.SUCCESS, fileId);
    }

    /**
     * 上传至fastDFS
     * @param multipartFile
     * @return 文件id
     */
    private String fdfsUpload(MultipartFile multipartFile) {
        // 1. 初始化fastDFS的环境
        initFdfsConfig();
        // 2. 获取trackerClient服务
        TrackerClient trackerClient = new TrackerClient();
        try {
            TrackerServer trackerServer = trackerClient.getConnection();
            // 3. 获取storage服务
            StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer);
            // 4. 获取storageClient
            StorageClient1 storageClient1 = new StorageClient1(trackerServer, storeStorage);
            // 5. 上传文件 (文件字节, 文件扩展名, )
            // 5.1 获取文件扩展名
            String originalFilename = multipartFile.getOriginalFilename();
            String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            // 5.2 上传
            String fileId = storageClient1.upload_file1(multipartFile.getBytes(), extName, null);
            return fileId;
        } catch (Exception e) {
            ExceptionCast.cast(FileSystemCode.FS_UPLOADFILE_SERVERFAIL);
            return null;
        }
    }

    /**
     * 初始化fastDFS的环境
     */
    private void initFdfsConfig() {
        try {
            ClientGlobal.initByTrackers(tracker_servers);
            ClientGlobal.setG_connect_timeout(connect_timeout);
            ClientGlobal.setG_network_timeout(network_timeout);
            ClientGlobal.setG_charset(charset);
        } catch (Exception e) {
            ExceptionCast.cast(FileSystemCode.FS_INIT_FDFS_ERROR);
        }
    }

启动项目,上传图片时报错连接超时,通过关闭centos的防火墙解决。

前端:
注意name这个属性的值是后端Controller层的@RequestParam值。

   
      
    

FastDFS实现上传文件(在Linux下安装与使用的详细步骤)_第6张图片
FastDFS实现上传文件(在Linux下安装与使用的详细步骤)_第7张图片


3、下面这个FastDFS客户端使用起来更简洁些。
依赖:

 		<dependency>
            <groupId>com.github.tobatogroupId>
            <artifactId>fastdfs-clientartifactId>
        dependency>

配置:

fdfs:
  so-timeout: 2500       # 读取时间
  connect-timeout: 600   # 连接超时时间
  thumb-image:           # 缩略图
    width: 100
    height: 100
  tracker-list:          # tracker服务配置地址列表
    - 192.168.58.129:22122

导入配置:

@Configuration
@Import(FdfsClientConfig.class)
// 解决jmx重复注册bean的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastClientImporter {

}

注入FastFileStorageClient后,可以直接调用其uploadFIle(),比上一种方法省去了手动设置配置信息,也不需要自己建立tracker连接、获取storage、再获得storageClient这些准备工作。

/**
 * @author Orcas
 * @version V1.0.0
 * @date 2018/11/7 6:50
 */
@Slf4j
@Service
@EnableConfigurationProperties(UploadProperties.class)
public class UploadService {

    @Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private UploadProperties prop;

    public String uploadImage(MultipartFile file) {
        // 1、校验文件类型
        String contentType = file.getContentType();
        if (!prop.getAllowTypes().contains(contentType)) {
            ExceptionCast.cast(ExceptionEnum.INVALID_FILE_TYPE);
        }
        // 2、校验文件内容
        try {
            BufferedImage image = ImageIO.read(file.getInputStream());
            if (image == null || image.getWidth() == 0 || image.getHeight() == 0) {
                ExceptionCast.cast(ExceptionEnum.INVALID_FILE_TYPE);
            }
        } catch (IOException e) {
            log.error("校验文件内容失败....{}", e);
            ExceptionCast.cast(ExceptionEnum.INVALID_FILE_TYPE);
        }

        try {
            // 3、上传到FastDFS
            // 3.1、获取扩展名
            String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
            // 3.2、上传
            StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), extension, null);
            // 返回路径
            return prop.getBaseUrl() + storePath.getFullPath();
        } catch (IOException e) {
            log.error("【文件上传】上传文件失败!....{}", e);
            ExceptionCast.cast(ExceptionEnum.UPLOAD_FILE_ERROR);
        }
    }
}

其中返回路径拼接从配置文件中读取
将下面的配置文件类注入

@ConfigurationProperties(prefix = "upload")
@Getter
@Setter
public class UploadProperties {

    private String baseUrl;

    private List<String> allowTypes;
}
 upload:
    base-url: http://img.orcas.com/
    allow-types:
      - image/jpeg
      - image/png
      - image/bmp

你可能感兴趣的:(项目相关,fastdfs,nginx)