Ubuntu Docker 安装 FastDFS 及使用

Ubuntu Docker 安装 FastDFS 及使用


一、安装

  1. 创建安装目录
mkdir /usr/local/docker/fastdfs/environment
cd /usr/local/docker/fastdfs/environment
  1. 创建 Dockerfile
FROM ubuntu:xenial
MAINTAINER topsale@vip.qq.com

# 更新数据源
WORKDIR /etc/apt
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse' > sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse' >> sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse' >> sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> sources.list
RUN apt-get update

# 安装依赖
RUN apt-get install make gcc libpcre3-dev zlib1g-dev --assume-yes

# 复制工具包
ADD fastdfs-5.11.tar.gz /usr/local/src
ADD fastdfs-nginx-module_v1.16.tar.gz /usr/local/src
ADD libfastcommon.tar.gz /usr/local/src
ADD nginx-1.13.6.tar.gz /usr/local/src

# 安装 libfastcommon
WORKDIR /usr/local/src/libfastcommon
RUN ./make.sh && ./make.sh install

# 安装 FastDFS
WORKDIR /usr/local/src/fastdfs-5.11
RUN ./make.sh && ./make.sh install

# 配置 FastDFS 跟踪器
ADD tracker.conf /etc/fdfs
RUN mkdir -p /fastdfs/tracker

# 配置 FastDFS 存储
ADD storage.conf /etc/fdfs
RUN mkdir -p /fastdfs/storage

# 配置 FastDFS 客户端
ADD client.conf /etc/fdfs

# 配置 fastdfs-nginx-module
ADD config /usr/local/src/fastdfs-nginx-module/src

# FastDFS 与 Nginx 集成
WORKDIR /usr/local/src/nginx-1.13.6
RUN ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src
RUN make && make install
ADD mod_fastdfs.conf /etc/fdfs

WORKDIR /usr/local/src/fastdfs-5.11/conf
RUN cp http.conf mime.types /etc/fdfs/

# 配置 Nginx
ADD nginx.conf /usr/local/nginx/conf

COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

WORKDIR /
EXPOSE 8888
CMD ["/bin/bash"]
  1. 解压 FastDFS.zip,并将文件夹中的内容复制到 environment 下。FastDFS.zip在我的阿里云盘下。
  2. 执行chmod +x entrypoint.sh赋予执行权限。
  3. 修改tracker.confg中的base_path配置
base_path=/fastdfs/tracker
  1. 修改storage.conf 中的基础配置,注意tracker_server为跟踪器地址,http.server_port为nginx监听端口
base_path=/fastdfs/storage
store_path0=/fastdfs/storage
tracker_server=192.168.3.37:22122
http.server_port=8888
  1. 修改client.conf,FastDFS客户端配置
base_path=/fastdfs/tracker
tracker_server=192.168.3.37:22122
  1. 修改 mod_fastdfs.conf (nginx插件)
connect_timeout=10
tracker_server=192.168.3.37:22122
url_have_group_name = true
store_path0=/fastdfs/storage
  1. nginx.conf
user  root;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       8888;
        server_name  localhost;

        location ~/group([0-9])/M00 {
            ngx_fastdfs_module;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
  1. environment文件夹同级下创建docker-compose.yml
version: '3.1'
services:
  fastdfs:
    build: environment
    restart: always
    container_name: fastdfs
    volumes:
      - ./storage:/fastdfs/storage
    network_mode: host
  1. 启动
docker-compose up -d

二、Springboot 集成

  1. 依赖
 <dependency>
     <groupId>net.oschina.zcx7878</groupId>
     <artifactId>fastdfs-client-java</artifactId>
     <version>1.27.0.0</version>
 </dependency>
  1. 工具类
package com.chorain.framework.service;

/**
 * @Description 文件存储服务接口
 * @Author yin.jinbiao
 * @Date 2021/7/13 17:23
 * @Version 1.0
 */
public interface StorageService {
    /**
     * 上传文件
     *
     * @param data    文件的二进制内容
     * @param extName 扩展名
     * @return 上传成功后返回生成的文件id;失败,返回null
     */
    String upload(byte[] data, String extName);

    /**
     * 删除文件
     *
     * @param fileId 被删除的文件id
     * @return 删除成功后返回0,失败后返回错误代码
     */
    int delete(String fileId);
}
package com.chorain.framework.service.impl;

import com.chorain.framework.service.StorageService;
import lombok.extern.slf4j.Slf4j;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Description 文件服务实现
 * @Author yin.jinbiao
 * @Date 2021/7/13 17:24
 * @Version 1.0
 */
@Slf4j
public class FastDFSStorageServiceImpl implements StorageService, InitializingBean {

    private TrackerClient trackerClient;

    @Value("${storage.fastdfs.tracker_server}")
    private String trackerServer;

    @Override
    public String upload(byte[] data, String extName) {
        TrackerServer trackerServer = null;
        StorageServer storageServer = null;
        StorageClient1 storageClient1 = null;
        try {
            NameValuePair[] meta_list = null; // new NameValuePair[0];

            trackerServer = trackerClient.getConnection();
            if (trackerServer == null) {
                log.error("getConnection return null");
            }
            storageServer = trackerClient.getStoreStorage(trackerServer);
            storageClient1 = new StorageClient1(trackerServer, storageServer);
            String fileid = storageClient1.upload_file1(data, extName, meta_list);
            log.debug("uploaded file <{}>", fileid);
            return fileid;
        } catch (Exception ex) {
            log.error("Upload fail", ex);
            return null;
        } finally {
            if (storageServer != null) {
                try {
                    storageServer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (trackerServer != null) {
                try {
                    trackerServer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            storageClient1 = null;
        }
    }

    @Override
    public int delete(String fileId) {
        TrackerServer trackerServer = null;
        StorageServer storageServer = null;
        StorageClient1 storageClient1 = null;
        int index = fileId.indexOf('/');
        String groupName = fileId.substring(0, index);
        try {
            trackerServer = trackerClient.getConnection();
            if (trackerServer == null) {
                log.error("getConnection return null");
            }
            storageServer = trackerClient.getStoreStorage(trackerServer, groupName);
            storageClient1 = new StorageClient1(trackerServer, storageServer);
            int result = storageClient1.delete_file1(fileId);
            return result;
        } catch (Exception ex) {
            log.error("Delete fail", ex);
            return 1;
        } finally {
            if (storageServer != null) {
                try {
                    storageServer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (trackerServer != null) {
                try {
                    trackerServer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            storageClient1 = null;
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        File confFile = File.createTempFile("fastdfs", ".conf");
        PrintWriter confWriter = new PrintWriter(new FileWriter(confFile));
        confWriter.println("tracker_server=" + trackerServer);
        confWriter.close();
        ClientGlobal.init(confFile.getAbsolutePath());
        confFile.delete();
        TrackerGroup trackerGroup = ClientGlobal.g_tracker_group;
        trackerClient = new TrackerClient(trackerGroup);

        log.info("Init FastDFS with tracker_server : {}", trackerServer);
    }
}
package com.chorain.framework.common.factory;

import com.chorain.framework.service.StorageService;
import com.chorain.framework.service.impl.FastDFSStorageServiceImpl;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description 文件存储服务工厂类
 * @Author yin.jinbiao
 * @Date 2021/7/13 17:29
 * @Version 1.0
 */
public class StorageFactory implements FactoryBean<StorageService> {

    @Autowired
    private AutowireCapableBeanFactory acbf;

    /**
     * 存储服务的类型,目前仅支持fastdfs
     */
    @Value("${storage.type}")
    private String type;

    private Map<String, Class<? extends StorageService>> classMap;

    public StorageFactory() {
        classMap = new HashMap<>();
        // fastdfs 方式
        classMap.put("fastdfs", FastDFSStorageServiceImpl.class);
    }

    @Override
    public StorageService getObject() throws Exception {
        Class<? extends StorageService> clazz = classMap.get(type);
        if (clazz == null) {
            throw new RuntimeException("Unsupported storage type [" + type + "], valid are " + classMap.keySet());
        }

        StorageService bean = clazz.newInstance();
        acbf.autowireBean(bean);
        acbf.initializeBean(bean, bean.getClass().getSimpleName());
        return bean;
    }

    @Override
    public Class<?> getObjectType() {
        return StorageService.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
package com.chorain.framework.common.config;

import com.chorain.framework.common.factory.StorageFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Java 配置方式定义 StorageFactory 的 Bean 使其可以被依赖注入
 * @Author yin.jinbiao
 * @Date 2021/7/13 17:30
 * @Version 1.0
 */
@Configuration
public class FastDFSConfiguration {
    @Bean
    public StorageFactory storageFactory() {
        return new StorageFactory();
    }
}

  1. 配置
fastdfs:
  base:
    url: http://192.168.3.37:8888/
storage:
  type: fastdfs
  fastdfs:
    tracker_server: 192.168.10.131:22122

三、小结

FastDFS 有三个概念:

  1. 跟踪器 tracker server ,主要做调度工作,起负载均衡作用,每个 storage 启动后会连接 tracker,告知自己所属的 group 等信息,并保持周期性心跳。
  2. 存储服务器 storage server,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。
  3. 客户端 client,上传下载数据的服务器。这里我们的服务代码就相当于一台客户端。

上述的 tracker 和 group 都仅有一个实例, 如果想做备份,可以加一台 storage server,group 配置相同即可。因为 相同的 group 互为备份。

所以想扩容,可以新加机器,通过增加新的 group 来实现。

多个 tracker server 的作用是相同的,Storage Server会定期的向Tracker Server发送自己的存储信息。当Tracker Server Cluster中的Tracker Server不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。

所以如果想实现负载均衡效果,可以通过添加 tracker server 来实现,修改每个 storage server 的配置,添加其 tracker_server 的配置即可。

参考资料

用FastDFS一步步搭建文件管理系统

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值