软件篇-分布式文件系统(over) - docker方式安装和Java客户端

分布式文件系统

1.简介

通过先前的例子我们发现普通的方式安装及其麻烦,假如我们需要搭建集群,那更加麻烦。所以在安装软件时并不推荐使用常规的方式去安装,而是推荐使用基于Docker方式去安装

2.镜像选择

要想基于Dokcer的方式去安装,那么我们就需要选择合适的镜像。为了更好的安装,我更换了一台计算机,其IP地址为172.16.0.4并安装了docker,搭建了私服。如果不知道安装,可以参考《Docker 使用系列》

  • 搜索镜像

    docker search fastdfs
    
    image-20200430133125682.png

    发现虽然镜像有很多,但是并没有官方所提供的。同时其他的镜像我们也不清楚别人构建的过程。因此我们可以自己制作一个镜像。

3. 制作镜像

3.1 镜像文件解释

我们可以从github来拉取一个制作镜像的Dockerfile.

  • 地址

    https://github.com/gzlj/fastdfs

  • 目录结构

    image-20200430133432204.png
  • 关于文件解释

    image-20200430133731835.png

    所需的软件

  • Dockerfile解释

    #基础镜像
    FROM centos:7
    #作者信息
    MAINTAINER liujun "[email protected]"
    
    #安装所需的依赖
    RUN yum install -y zlib zlib-devel pcre pcre-devel gcc gcc-c++ openssl openssl-devel libevent libevent-devel perl unzip
    
    #安装 libfastcommon
    #将libfastcommon-1.0.35.zip 复制到 /usr/local/src/ 
    ADD libfastcommon-1.0.35.zip /usr/local/src/
    # 进入到 /usr/local/src 并解压,同时还编译和运行
    RUN cd /usr/local/src \
        && unzip /usr/local/src/libfastcommon-1.0.35.zip \
        && cd libfastcommon-1.0.35 \
        && ./make.sh \
        && ./make.sh install
    
    #安装 fastdfs
    # 将fastdfs-5.11.zip 复制到 /usr/local/src/下
    ADD fastdfs-5.11.zip /usr/local/src/
    # 解压
    RUN cd /usr/local/src/ && unzip fastdfs-5.11.zip
    # 编译安装,同时将配置复制到 /etc/fdfs下
    RUN cd /usr/local/src/fastdfs-5.11 \
    && ./make.sh \
    && ./make.sh install \
    && cp conf/*.conf /etc/fdfs \
    && cd /etc/fdfs/ \
    && rm -rf *.sample
    
    #安装nginx
    #将fastdfs-nginx-module_v1.16.tar.gz 复制 /usr/local/src/
    ADD fastdfs-nginx-module_v1.16.tar.gz /usr/local/src/
    #ADD fastdfs-nginx-module-1.20.zip /usr/local/src/
    #run cd /usr/local/src/ && unzip fastdfs-nginx-module-1.20.zip && ln -s fastdfs-nginx-module-1.20 fastdfs-nginx-module
    
    #将nginx-1.7.8.tar.gz 复制 /usr/local/src/
    ADD nginx-1.7.8.tar.gz /usr/local/src/
    # 添加模块,编译安装nginx
    RUN cd /usr/local/src/ \
        && cd nginx-1.7.8 \
        && ./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/fastdfs-nginx-module/src \
        && make \
        && make install \
        && cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
    # 复制 nginx.conf 到 /usr/local/nginx/conf/
    ADD nginx.conf /usr/local/nginx/conf/
    
    #创建 storage和tracker 存储日志和数据目录
    RUN mkdir -p /export/fastdfs/{storage,tracker}
    # 将脚本复制到 /usr/local/src/
    ADD tracker.sh /usr/local/src/
    ADD storage.sh /usr/local/src/
    
  • nginx.conf解释

    #user  nobody;
    worker_processes  1;
    
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
    
    #pid        logs/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
        #access_log  logs/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        #keepalive_timeout  0;
        keepalive_timeout  65;
    
        #gzip  on;
    
        server {
            # 默认监听 8080,这个在创建容器时可以更换
            listen       8080;
            # 监听域名为本机
            server_name  localhost;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            # 如果发送的请求中,包含group 交给ngx_fastdfs_module 处理
            location ~/group[1-9]/M00 {
                root /export/fastdfs/storage/data;
                ngx_fastdfs_module;
            }
    
            #error_page  404              /404.html;
    
            # redirect server error pages to the static page /50x.html
            #
            # 错误页面
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
    
            # proxy the PHP scripts to Apache listening on 127.0.0.1:80
            #
            #location ~ \.php$ {
            #    proxy_pass   http://127.0.0.1;
            #}
    
            # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
            #
            #location ~ \.php$ {
            #    root           html;
            #    fastcgi_pass   127.0.0.1:9000;
            #    fastcgi_index  index.php;
            #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            #    include        fastcgi_params;
            #}
    
            # deny access to .htaccess files, if Apache's document root
            # concurs with nginx's one
            #
            #location ~ /\.ht {
            #    deny  all;
            #}
        }
    
    
        # another virtual host using mix of IP-, name-, and port-based configuration
        #
        #server {
        #    listen       8000;
        #    listen       somename:8080;
        #    server_name  somename  alias  another.alias;
    
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
    
    
        # HTTPS server
        #
        #server {
        #    listen       443 ssl;
        #    server_name  localhost;
    
        #    ssl_certificate      cert.pem;
        #    ssl_certificate_key  cert.key;
    
        #    ssl_session_cache    shared:SSL:1m;
        #    ssl_session_timeout  5m;
    
        #    ssl_ciphers  HIGH:!aNULL:!MD5;
        #    ssl_prefer_server_ciphers  on;
    
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
    
    }
    
    
  • tracker.sh解释

    #!/bin/sh
    if [ ! -f /initialized ]; then {
    touch /initialized
    #TRACKER_PORT 创建容器时需要手动指,如果采用默认的话,可以把这行删掉
    sed -i "s#\(port\).*#\1=$TRACKER_PORT#" /etc/fdfs/tracker.conf
    #TRACKER_BASE_PATH 创建容器时需要手动指定
    sed -i "s#\(base_path\).*#\1=$TRACKER_BASE_PATH#" /etc/fdfs/tracker.conf
    }
    fi
    # 重启 tracker
    /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
    # 展示日志
    tail -f /export/fastdfs/tracker/logs/trackerd.log
    
  • storage.sh 解释

    #!/bin/sh
    if [ ! -f /initialized ]; then {
      touch /initialized
      # STORAGE_PORT 创建容器时需要手动指定,如果采用默认的话,可以把这行删掉
      sed -i "s#\(port\).*#\1=$STORAGE_PORT#" /etc/fdfs/storage.conf
      
      # GROUP_NAME 创建容器时需要手动指定组名,如果采用默认的话,可以把这行删掉
      sed -i "s#\(group_name\).*#\1=$GROUP_NAME#" /etc/fdfs/storage.conf
      
      # STORAGE_BASE_PATH 创建容器时需要手动指定存储日志和数据的目录
      sed -i "s#\(base_path\).*#\1=$STORAGE_BASE_PATH#" /etc/fdfs/storage.conf
      
      # STORAGE_BASE_PATH 创建容器时需要手动指定文件上传的存储目录
      sed -i "s#\(store_path0\).*#\1=$STORAGE_PATH0#" /etc/fdfs/storage.conf
    
      # 创建容器时手动指定tracker_server
      sed -i "s#\(tracker_server\).*##" /etc/fdfs/storage.conf
      
      #HTTP_SERVER_PORT 创建容器时手动指定
      sed -i "s#\(http.server_port\).*#\1=$HTTP_SERVER_PORT#" /etc/fdfs/storage.conf
      
      # STORAGE_BASE_PATH 创建容器时 指定 STORAGE_BASE_PATH 的值是mod_fastdfs.conf存储日志和数据的目录
      sed -i "s#\(base_path\).*#\1=$STORAGE_BASE_PATH#" /etc/fdfs/mod_fastdfs.conf
      
      # STORAGE_PATH0 创建容器时 指定 STORAGE_PATH0文件上传的存储路径
      sed -i "s#\(store_path0\).*#\1=$STORAGE_PATH0#" /etc/fdfs/mod_fastdfs.conf
      
      #  STORAGE_PORT 手动指定端口,想要默认可以直接删掉
      sed -i "s#\(storage_server_port\).*#\1=$STORAGE_PORT#" /etc/fdfs/mod_fastdfs.conf
    
      # 设置 mod_fastdfs 的 tracker_server
      sed -i "s#\(tracker_server\).*##" /etc/fdfs/mod_fastdfs.conf
      
      # GROUP_NAME 设置组名
      sed -i "s#\(group_name\).*#\1=$GROUP_NAME#" /etc/fdfs/mod_fastdfs.conf
      
      # GROUP_COUNT 设置组的数量
      sed -i "s#\(group_count\).*#\1=$GROUP_COUNT#" /etc/fdfs/mod_fastdfs.conf
    
      # 设置 HTTP_SERVER_PORT 端口
      sed -i "s#\(http.server_port\).*#\1=$HTTP_SERVER_PORT#" /etc/fdfs/mod_fastdfs.conf
      
      #设置组名
      sed -i "s#\(url_have_group_name\).*#\1=true#" /etc/fdfs/mod_fastdfs.conf
      
      # 这个非常重要,将HTTP_SERVER_PORT 的值设置为Nginx的监听端口
      sed -i "s#listen       8080#listen       $HTTP_SERVER_PORT#g" /usr/local/nginx/conf/nginx.conf
      for i in $( echo $TRACKER_SERVER | awk -v FS="," '{for(i=1;i<=NF;i++)print $i}'  );do echo "tracker_server=$i" >> /etc/fdfs/storage.conf;done
      for i in $( echo $TRACKER_SERVER | awk -v FS="," '{for(i=1;i<=NF;i++)print $i}'  );do echo "tracker_server=$i" >> /etc/fdfs/mod_fastdfs.conf;done
    
      #add groups 添加组
      i=1
      while(( $i<=$GROUP_COUNT ))
      do
      # 设置组信息
      echo "[group$i]" >> /etc/fdfs/mod_fastdfs.conf
      
      # 设置组名
      echo "group_name=group$i" >> /etc/fdfs/mod_fastdfs.conf
      
      # 设置组的端口
      echo "storage_server_port=$STORAGE_PORT" >> /etc/fdfs/mod_fastdfs.conf
      
      # 设置组的存储路径数量
      echo "store_path_count=1" >> /etc/fdfs/mod_fastdfs.conf
      
      # 设置组的文件存储路径
      echo "store_path0=$STORAGE_PATH0" >> /etc/fdfs/mod_fastdfs.conf
      let "i++"
      done
    }
    fi
    
    cd /etc/fdfs
    touch mime.types
    /usr/local/nginx/sbin/nginx -t
    /usr/local/nginx/sbin/nginx
    
    # 启动storage 
    /usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
    
    #展示日志
    tail -f /export/fastdfs/storage/logs/storaged.log
    

3.2 镜像制作

  • 根据上述中的 liujun 给我们提供的制作镜像的文件下载下来,并上传到 计算机上

    image-20200430140508262.png
  • 下载 unzip 并解压

    image-20200430140538812.png
  • 进入解压好的目录下,进行构建

    docker build -t 宿主机Ip:私服端口/fastdfs:5.11 .
    这个格式的镜像可以直接推送到私服,不用起别名
    
    image-20200430142223145.png
    image-20200430142726739.png

镜像构建成功

  • 上传到私服

    docker push 172.16.0.47:5000/fastdfs:5.11
    

    成功后访问私服:

    image-20200430142921025.png

    上传成功。

3.3 创建容器

这里我们创建一个tracker容器和一个storage容器,当然可以创建集群,无非是多创建几个容器。

但是我们在一台宿主机搭建集群意义也不大,如果多台机器的话,都是重复工作。如果有实际需求可以自己动手搭建。可以参考上述文件中的READ ME.md

3.3.1 创建并运行容器

  • 创建并运行容器(tracker)

    docker run -di --name=fdfs_tracker -v /var/fdfs/tracker:/export/fastdfs/tracker  --net=host -e TRACKER_BASE_PATH=/export/fastdfs/tracker  -e TRACKER_PORT=22123 172.16.0.47:5000/fastdfs:5.11 sh /usr/local/src/tracker.sh
    

    -v /var/fdfs/tracker 将track容器存储数据的目录映射到宿主机上

    --net=host 网络模式,映射容器上所有端口

    -e TRACKER_BASE_PATH=/export/fastdfs/tracker 设置tracker容器内存储日志和数据的目录,不要改

    -e TRACKER_PORT=22123 设置track的端口

    sh /usr/local/src/tracker.sh 执行容器里面的脚本

    image-20200430150103063.png
  • 创建并运行容器(storage)

    docker run -di --name=fdfs_storage -v /var/fastdfs/storage:/export/fastdfs/storage --net=host -e STORAGE_PORT=23001 -e STORAGE_BASE_PATH=/export/fastdfs/storage -e STORAGE_PATH0=/export/fastdfs/storage -e TRACKER_SERVER=172.16.0.47:22123 -e GROUP_COUNT=1 -e HTTP_SERVER_PORT=8081  -e GROUP_NAME=group1 172.16.0.47:5000/fastdfs:5.11  sh /usr/local/src/storage.sh
    

    -v /var/fdfs/tracker 将track容器存储数据的目录映射到宿主机上

    --net=host 网络模式,映射容器上所有端口

    -e STORAGE_PORT=23001 设置storage的端口

    -e STORAGE_BASE_PATH=/export/fastdfs/storage 设置 storage容器内存储日志和数据的位置,不要改

    -e STORAGE_PATH0 =/export/fastdfs/storage 设置文件上传的存储路径

    -e TRACKER_SERVER=172.16.0.47:22123 设置tracker_server设置地址

    -e GROUP_COUNT=1 设置组的数量为1

    -e HTTP_SERVER_POR=8081 设置storage的http端口和nginx的监听端口

    -e GROUP_NAME=group1 设置组名

    sh /usr/local/src/storage.sh 执行storage脚本

3.3.2 测试

进入storage容器中,测试是否与tracker进行了连接

docker exec -it fdfs_storage  /bin/bash
image-20200430151716789.png

测试命令

 /usr/bin/fdfs_monitor /etc/fdfs/storage.conf 
image-20200430151824548.png

连接成功。

通过浏览器访问,也可以看到nginx

image-20200430151922551.png

4.Java客户端连接

4.1 简介

FastDFS的作者余庆先生也给我们提供一个java客户端用来连接 FastDFS,但是已经很久不维护了。但是在GitHub上有一款开源的FastDFS客户端。 这个客户端得到了在原来余庆先生提供的客户端基础上进行大量的重构

配置及其简单,支持连接池,支持自动生成缩略图,同时还支持SpringBoot 2.x

地址:https://github.com/tobato/FastDFS_Client

image-20200430152747762.png

4.2 编码

4.2.1 上传普通文件

  • 创建SpringBoot项目并导入依赖(springboot 版本:2.1.13.RELEASE)

    image-20200430153304493.png

     com.github.tobato
      fastdfs-client
      1.27.2

  • 修改application.yml文件,增加配置

    image-20200430153404158.png
    fdfs:
      connect-timeout: 600
      so-timeout: 1501
      tracker-list: # tracker地址
        - 172.16.0.47:22123
    
  • 增加配置类

    package com.wangzh.fastdfs.config;
    
    import com.github.tobato.fastdfs.FdfsClientConfig;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableMBeanExport;
    import org.springframework.context.annotation.Import;
    import org.springframework.jmx.support.RegistrationPolicy;
    
    @Configuration
    @Import(FdfsClientConfig.class)
    // 解决jmx重复注册问题
    @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
    public class FastDFSClientConfig {
    }
    
    
  • 测试上传普通文件

    package com.wangzh.fastdfs;
    
    import com.github.tobato.fastdfs.domain.fdfs.StorePath;
    import com.github.tobato.fastdfs.service.FastFileStorageClient;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class FastdfsApplicationTests {
    
        /**
         *
         *  注入上传的客户端对象
         */
        @Autowired
        private FastFileStorageClient storageClient;
    
    
    
        @Test
        public void upload() throws FileNotFoundException {
            File file = new File("C:\\Users\\wangzh\\Desktop\\html.pdf");
            /*
             *  第一个参数 为组名,不写 默认group1
             *  第二个参数为文件流
             *  第三个参数为上传文件的大小
             *  第四个参数为 文件后缀名
             * */
            StorePath storePath = storageClient.uploadFile("group1", new FileInputStream(file), file.length(), "pdf");
    
            /*
             * 打印文件名Id 包含组名
             *  执行后的结果为: group1/M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
             *   group1  组名 
             *     M00 代表设置的  storage_path0
                 00/00 存储的具体磁盘目录
             *    rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
             */
            System.out.println(storePath.getFullPath());
    
            /*
            *   打印文件名,不包含组名
            *     执行后的结果为:     M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
            * */
            System.out.println(storePath.getPath());
    
    
        }
    
    
    }
    
    

    访问:

    http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
    
    image-20200430155108327.png

    文件上传成功。

4.2.2 上传图片

上传图片并自动创建缩略图

  • 增加缩略图配置

    image-20200430155651106.png
    fdfs:
      connect-timeout: 600
      so-timeout: 1501
      tracker-list: # tracker地址
        - 172.16.0.47:22123
      thumb-image:
        width: 70
        height: 70
    
  • 编码

    package com.wangzh.fastdfs;
    
    import com.github.tobato.fastdfs.domain.fdfs.StorePath;
    import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig;
    import com.github.tobato.fastdfs.service.FastFileStorageClient;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class FastdfsApplicationTests {
    
        /**
         *
         *  注入上传的客户端对象
         */
        @Autowired
        private FastFileStorageClient storageClient;
    
    
        /**
         * 注入缩略图配置对象
         */
        @Autowired
       private ThumbImageConfig thumbImageConfig;
    
        @Test
        public void testUpload() throws FileNotFoundException {
            File file = new File("D:\\1_soft\\1.jpg");
            StorePath storePath = storageClient.uploadImageAndCrtThumbImage(new FileInputStream(file), file.length(), "jpg", null);
            System.out.println("带分组路径:" + storePath.getFullPath());
            System.out.println("不带分组路径:" + storePath.getPath());
            System.out.println("获取缩略图路径:" + thumbImageConfig.getThumbImagePath(storePath.getPath()));
    
        }
    
    
    
    }
    
    

    结果:

    带分组路径:group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg
    不带分组路径:M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg
    获取缩略图路径:M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269_70x70.jpg
    

    我们通过浏览器访问一下:

    http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269_70x70.jpg
    
    image-20200430160108928.png
    http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg
    
    image-20200430160208936.png

你可能感兴趣的:(软件篇-分布式文件系统(over) - docker方式安装和Java客户端)