首先来大致上介绍一下fastdfs

它是一个分布式文件存储系统,适用于中小文件的存储.建议范围:4KB < file_size <500MB)为载体的在线服务,主要解决了海量数据存储问题.

并且是开源的.

主要组成:

1,tracker 跟踪器.

主要用来协调客户端的请求.且在内存中记录所有存储组和存储服务器的信息状态。

2,storage 存储器

用来存储文件(data)和文件属性(metadata)

3,client 客户端

业务请求发起方,通过专用接口基于TCP协议与tracker以及storage server进行交互

4,group 组

在同组内的数据是相同的,同组内的storage相当于mysql的主从一样.可以达到高可用性.

同步机制:

1,同一组内的storage是相对等的,文件的上传下载可以在任意一台上进行

2,文件同步只在storage之间进行,采用push方式

与mogileFS的对比

java 服务端生成的图片分布式缓存 java分布式文件存储_fish

与集中存储的对比

java 服务端生成的图片分布式缓存 java分布式文件存储_java 服务端生成的图片分布式缓存_02

FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。

java 服务端生成的图片分布式缓存 java分布式文件存储_java 服务端生成的图片分布式缓存_03

下面我们将fastdfs与springmvc进行整合

首先引入依赖

<dependency>
     <groupId>org.csource</groupId>
     <artifactId>fastdfs-client-java</artifactId>
     <version>1.27-SNAPSHOT</version>
 </dependency>

如果没有依赖,需要自行去官网下载源码打包

源码地址: https://github.com/happyfish100/fastdfs-client-java

创建fasfFile对象

public class FastDFSFile {
    private byte[] content;
    private String name;
    private String ext;
    private String length;

    public FastDFSFile(byte[] content, String ext) {
        this.content = content;
        this.ext = ext;
    }

    public FastDFSFile(byte[] content, String name, String ext) {
        this.content = content;
        this.name = name;
        this.ext = ext;
    }

    public FastDFSFile(byte[] content, String name, String ext, String length) {
        this.content = content;
        this.name = name;
        this.ext = ext;
        this.length = length;
    }

get /set 方法忽略.你们自行加上即可

创建上传下载工具类:

public class FileManager {
    private static TrackerClient trackerClient;
    private static TrackerServer trackerServer;
    private static StorageServer storageServer;
    private static StorageClient storageClient;

    static {
        try {
            String classPath = FileManager.class.getClassLoader().getResource("fdfs_client.conf").getPath();
            ClientGlobal.init(classPath);
            trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
            trackerServer = trackerClient.getConnection();
            storageServer= trackerClient.getStoreStorage(trackerServer);
            storageClient = new StorageClient(trackerServer, storageServer);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * <strong>方法概要: 文件上传</strong> <br>
     * <strong>创建时间: 2016-9-26 上午10:26:11</strong> <br>
     *
     * @param
     *            file
     * @return fileAbsolutePath
     * @author 吕金刚
     */
    public static String upload(FastDFSFile file,NameValuePair[] valuePairs) {
        String[] uploadResults = null;
        try {
            uploadResults = storageClient.upload_file("group1",file.getContent(),file.getExt(),valuePairs);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return uploadResults[1];
    }

    /**
     * 删除文件
     * @param fileUrl
     */
    public static void deletefile(String fileUrl){
        try {
            final int group1 = storageClient.delete_file("group1", fileUrl);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件下载
     * @param fileUrl
     * @return
     */
    public static byte[] download(String fileUrl){
        byte[] group1s = null;
        try {
            group1s = storageClient.download_file("group1", fileUrl);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return group1s;
    }

    /**
     * 获取文件元数据
     * @param fileId 文件ID
     * @return
     */
    public Map<String,String> getFileMetadata(String groupname, String fileId) {
        try {
            NameValuePair[] metaList = storageClient.get_metadata(groupname,fileId);
            if (metaList != null) {
                HashMap<String,String> map = new HashMap<String, String>();
                for (NameValuePair metaItem : metaList) {
                    map.put(metaItem.getName(),metaItem.getValue());
                }
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

引入配置文件

fdfs_client.conf

connect_timeout = 2
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 8080
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
tracker_server = 192.168.68.128:22122

在看控制层方法,此处是简单的demo,实战中自行封装

@RequestMapping("imgfile")
    public String imgfile(@RequestParam("imgfile")MultipartFile multipartFile, HttpServletRequest request) throws IOException {

        String ext = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".")+1);
        FastDFSFile file = new FastDFSFile(multipartFile.getBytes(),ext);
        NameValuePair[] meta_list = new NameValuePair[3];
        meta_list[0] = new NameValuePair("fileName", multipartFile.getOriginalFilename());
        meta_list[1] = new NameValuePair("fileLength", String.valueOf(multipartFile.getSize()));
        meta_list[2] = new NameValuePair("fileExt", ext);
        String filePath = FileManager.upload(file,meta_list);
        System.out.println(filePath+"---------------------------------------");
        return "redirect:/filePath";
    }

我下返回的文件路径

java 服务端生成的图片分布式缓存 java分布式文件存储_nginx_04

在实际硬盘中的存储如图

java 服务端生成的图片分布式缓存 java分布式文件存储_java 服务端生成的图片分布式缓存_05

我们通过nginx与fastdfs进行整合后通过浏览器访问图片路径

java 服务端生成的图片分布式缓存 java分布式文件存储_nginx_06

返回的路径含义如下:

java 服务端生成的图片分布式缓存 java分布式文件存储_fish_07

我们将返回的路径存储到关系型数据库中即可.

下面我带你们搭建一个单机版的环境,

首选我的环境如下:

1,两台linux centos 7.2d的机器两台.

192.168.68.128 安装tracker

192.168.68.139 安装storage和nginx

2,下载软件安装包以及依赖

下载软件fastdfs包 :https://github.com/happyfish100/fastdfs/releases

下载 libfastcommon包: https: //github.com/happyfish100/libfastcommon/releases

安装 gcc yum install make cmake gcc gcc-c++

3、安装libfastcommon(俩台机器同时进行)

a 上传libfastcommon_v1.0.36.tar.gz到/usr/local/gang下

b 进行解压libfastcommon_v1.0.36.tar.gz:

命令:tar -zxvf libfastcommon_v1.0.36.tar.gz -C /usr/local/fast 4 ,进入目录:cd /usr/local/fast/libfastcommon/

./make.sh

./make.sh install

5,安装fastdfs

a, 进入到cd /usr/local/gang下,解压fastdfs-5.11.tar.gz文件

命令:cd /usr/local/software

命令:tar -zxvf fastdfs-5.11.tar.gz -C /usr/local/fast/

b,安装编译

命令:cd /usr/local/fast/ fastdfs-5.11/

编译命令:./make.sh

安装命令:./make.sh install

接下来配置128上的跟踪器tracker

1,进入 cd /etc/fdfs/目录配置跟踪器文件,把tracker.conf.sample文件进行cope一份:去修改tracker.conf文件

vi /etc/fdfs/tracker.conf 将base_path配置成自己的路径

关于tracker.conf配置参考文章 http://bbs.chinaunix.net/thread-1941456-1-1.html

3,进行端口开放:

firewall-cmd --add-port=22122/tcp --permanent &

4,运行跟踪器

cd /fastdfs/tracker/ && ll 启动tracker命令:/etc/init.d/fdfs_trackerd start

接下来配置存储器storage139的机器上

1 进入文件目录:cd /etc/fdfs/,进行copy storage文件一份

命令:cd /etc/fdfs/

命令:cp storage.conf.sample storage.conf

2 修改storage.conf文件

命令:vim /etc/fdfs/storage.conf

修改内容:

base_path=/fastdfs/storage

store_path0=/fastdfs/storage

tracker_server=192.168.68.128:22122

http.server_port=8888

4,开放端口:

firewall-cmd --add-port=8888/tcp --permanent &

5,启动storage

命令:/etc/init.d/fdfs_storaged start

1,下载整合包

https://ftp.pcre.org/pub/pcre/

http://nginx.org/en/download.html

https://github.com/happyfish100/fastdfs-nginx-module

2,安装pcre

tar xf pcre-8.40.tar.gz

cd pcre-8.40

./configure --prefix=/usr/local/fast/pcre

make && make install

3 然后我们在存储节点上(192.168.68.139)安装fastdfs-nginx-module-master.zip包进行整合。

解压命令:unzip /usr/local/gang/fastdfs-nginx-module-master.zip -d/usr/local/fast/

4,安装nginx

加入模块命令:./configure --add-module=/usr/local/fast/fastdfs-nginx-module/src/

编译命令:make && make install

5,复制fastdfs-ngin-module中的配置文件,到/etc/fdfs目录中

copy命令:cp /usr/local/fast/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/

6进行修改 /etc/fdfs/ 目录下,我们刚刚copy过来的mod_fastdfs.conf 文件。

命令:vi /etc/fdfs/mod_fastdfs.conf

修改内容:比如连接超时时间、跟踪器路径配置、url的group配置、

connect_timeout=10

tracker_server=192.168.68.128:22122

url_have_group_name = true

store_path0=/fastdfs/storage

7,复制FastDFS里的2个文件,到/etc/fdfs目录中,如图所示

目录命令:cd /usr/local/fast/fastdfs-5.11/conf/

cp http.conf mime.types /etc/fdfs/

8,创建一个软连接,在/fastdfs/storage文件存储目录下创建软连接,将其链接到实际存放数据的目录。

命令:ln -s /fastdfs/storage/data/ /fastdfs/storage/data/M00

listen 8888;       
       
server_name localhost;       
       
location ~/group([0-9])/M00 {       
       
#alias /fastdfs/storage/data;       
       
ngx_fastdfs_module;       
       
}

实际成产中需要搭建集群方式,已达到高可用,高并发,可以通过增加组,进而横向扩展文件的存储容量.

实际生产中集群架构建议:

java 服务端生成的图片分布式缓存 java分布式文件存储_nginx_08

多storage 多tracker 紧密结合nginx使用

个人能力有限,有错误之处还望指出