分布式文件存储系统fastdfs与springmvc的整合

首先来大致上介绍一下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的对比
与集中存储的对比


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



下面我们将fastdfs与springmvc进行整合
首先引入依赖
<dependency>
     <groupId>org.csource</groupId>
     <artifactId>fastdfs-client-java</artifactId>
     <version>1.27-SNAPSHOT</version>
 </dependency>
如果没有依赖,需要自行去官网下载源码打包
创建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";
    }

我下返回的文件路径



在实际硬盘中的存储如图



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



返回的路径含义如下:



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

下面我带你们搭建一个单机版的环境,
首选我的环境如下:
1,两台linux centos 7.2d的机器两台.
192.168.68.128 安装tracker
192.168.68.139 安装storage和nginx
2,下载软件安装包以及依赖
下载 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文件
2, 修改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

接下来整合nginx与fasdfs
1,下载整合包
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
9,修改Nginx配置文件
listen 8888;
server_name localhost;
location ~/group([0-9])/M00 {
#alias /fastdfs/storage/data;
ngx_fastdfs_module;
}
到此单机版的已经安装完毕
实际成产中需要搭建集群方式,已达到高可用,高并发,可以通过增加组,进而横向扩展文件的存储容量.
实际生产中集群架构建议:

多storage 多tracker 紧密结合nginx使用

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

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值