本文主要讲述的是在 Docker 下部署 FastDFS 文件管理系统,使用 Nginx 来提供 Http 服务。
![c72ec03cd9c81c325bb7f982c0ad13ea.png](https://img-blog.csdnimg.cn/img_convert/c72ec03cd9c81c325bb7f982c0ad13ea.png)
FastDFS
简介
FastDFS 是一个开源的轻量级高性能的分布式文件系统(DFS,Distributed File System),C语言实现,不是通用的文件系统,只能通过专有的API进行访问(提供有C、Java和PHP API)。
它的主要功能:文件存储、文件同步和文件访问,以及高容量和负载均衡,特别适合中小文件(4kb - 500mb)为载体的在线服务。
![63d95039f38ec9515f050341e3862311.png](https://img-blog.csdnimg.cn/img_convert/63d95039f38ec9515f050341e3862311.png)
角色
tracker-server:跟踪服务器,主要调度工作,起负载均衡的作用。在内存中记录集群中所有存储组和存储服务器的状态信息, 是客户端和数据服务器交互的枢纽。负责管理所有的 storage server 和 group,每个 storage 在启动后会连接 Tracker。
storage-server:存储服务器 ( 又称:存储节点或数据服务器 ),文件和文件属性 ( metadata ) 都保存到存储服务器上。 Storage server 直接利用 OS 的文件系统调用管理文件。
client:客户端,也就是我们自己部署项目的服务器。
![d931f2a93371fbef9e8a2135229a9734.png](https://img-blog.csdnimg.cn/img_convert/d931f2a93371fbef9e8a2135229a9734.png)
存储策略
为了支持大容量,存储节点 ( 服务器 ) 采用分卷 ( 分组 ) 的组织方式。存储系统由多个或单个卷组成,卷与卷之间的文件是相互独立的,所有卷累加起来的文件容量就是存储系统的容量。一个卷可以有单个或多个存储服务器组成,一个卷下的存储服务器内的文件都是相同的,卷中多台的存储服务器起到冗余备份与负载均衡的作用。
上传过程
FastDFS 向使用者提供基本文件访问接口,如 Upload、Download,Append,Delete 等,以客户端库的形式提供给用户使用。
storage-server 会定期向 tracker-server 发送自身的存储信息。当 tracker-server-cluster 中 不止一个 tracker-server 时,各个 tracker 之间的关系是对等的,所以客户端上传时可以选择任意一个 tracker,当 tracker 收到客户端发送的上传请求时,会为该文件分配一个存储的 group,选定 group 后接下来就是为客户端分配 group 内的哪个 storage-server 了,得到 storage-server 后,客户端向 storage 发送写文件的请求,storage 则会为客户端分配一个数据存储目录,分配一个 fileid,根据以上信息再生成相应的文件名,将文件写入磁盘,最后返回存储文件信息给客户端。
![c6469154b350c46e266a2594ccb0629c.png](https://img-blog.csdnimg.cn/img_convert/c6469154b350c46e266a2594ccb0629c.png)
文件同步
写文件时,客户端将文件写到 group 中的一个 storage 后就算文件写入成功了。storage-server 文件写入成功后,会由后台线程将文件同步至同个 group 下的其它 storage-server。每个 storage-server 写文件时,都会生成一个 binlog 文件,该文件主要记录文件的元信息 ( 不是文件数据 ),该文件主要用于后台同步,storage 会记录向其它 storage 同步进度,以便在服务器重启后,能接上进度,继续进行同步。而进度主要也以时间戳的方式进行保存,所以最好能保证集群内的所有服务器时间一致。
storage 的同步进度,也会汇报至 tracker 中,tracker 在选择 storage 时以此作为参考。
![0a901318fe4d35763cc91d28454811a5.png](https://img-blog.csdnimg.cn/img_convert/0a901318fe4d35763cc91d28454811a5.png)
文件下载
客户端进行 Upload 操作后,会得到一个 storage 生成的文件名,而文件下载、访问等就直接通过该文件名来。
客户端在执行 Download 时,发送下载请求给 tracker-server,tracker-server 会任意选择一个 tracker,tracker 根据客户端提供的文件名信息,解析出 group、size、time 等信息,之后为该请求选择一个 storage 来服务客户端发起的下载请求。
废话了那么多,对FastDFS有个大概的了解后,正式进入主题,从 Docker 镜像开始,一步一步来部署,构建我们自己的文件管理系统。
![edf5767bd4bb817982f46497093d9cb8.png](https://img-blog.csdnimg.cn/img_convert/edf5767bd4bb817982f46497093d9cb8.png)
构建镜像
起初我搜索 docker search fastdfs,然后直接拉取了 season/fastdfs 镜像,但不含 nginx,本来我这个服务器中的 nginx 又是单独启动的一个容器,如果重新编译 nginx,无法单独增加 nginx_fastdfs_module 扩展模块,需要先安装 fastdfs 及 libfastcommon,所以干脆就重新写了一份 Dockerfile,自己制作镜像,同时 nginx 也用该镜像,不再单独启动 nginx 镜像,Dockerfile 具体内容如下 ( 同时加载了多个配置文件,一并附上配置文件 ) 。
# 源码我放在这儿了https://git.makeit.vip/MIITVIP/MIIT-Docker-Nginx-FastDFS# 拉取源码后,在 Dockerfile 所在目录下执行如下命令[root@makeit build]# docker build -t miitvip/nginx-fastdfs .# 花费几分钟,制作完成后,执行 docker images 进行镜像查看[root@makeit build]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEmiitvip/nginx-fastdfs latest 69d6ae812345 9 seconds ago 33.1MB
该镜像已经 push 至 docker hub,可直接通过 docker pull miitvip/nginx-fastdfs 进行镜像拉取
![f48045d848bdd47dc3204f0109bc176e.png](https://img-blog.csdnimg.cn/img_convert/f48045d848bdd47dc3204f0109bc176e.png)
运行镜像
fastdfs 相关的配置文件目录在 /etc/fastdfs,可执行文件在 /usr/bin 中
nginx 的配置目录在 Dockerfile 中已有指定,在 /etc/nginx,nginx 可执行文件在 /usr/sbin/nginx
在启动容器时,直接将所有相关的配置文件都映射到宿主机,便于修改 ( 可根据需求进行调整 )
# 运行之前,创建好相应的文件目录# 目录可自行创建,只要待会儿映射的时候能对上即可mkdir -p /makeit/logs/nginx /makeit/docker/nginx/ /makeit/docker/nginx/ssl /makeit/docker/nginx/letsencrypt /makeit/docker/fastdfs/tracker /makeit/docker/fastdfs/storage /makeit/docker/fastdfs/client /makeit/docker/fastdfs/conf /makeit/web/fastdfs# 启动 nginxdocker run -d -ti --name nginx -p 80:80 -p 443:443 -v /makeit/web:/www -v /makeit/logs/nginx:/var/log/nginx -v /makeit/docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -v /makeit/docker/nginx/conf.d:/etc/nginx/conf.d -v /makeit/docker/nginx/ssl:/etc/nginx/ssl -v /makeit/docker/nginx/letsencrypt:/etc/nginx/letsencrypt -v /makeit/web/fastdfs:/fastdfs/store --restart=always miitvip/nginx-fastdfs nginx# 启动 fastdfsdocker run -d -ti --name fastdfs -p 8888:8888 -p 22122:22122 -p 23000:23000 -e GROUP_NAME=MIIT -e TRACKER_SERVER=你服务器的IP -v /makeit/docker/fastdfs/tracker:/fastdfs/tracker -v /makeit/docker/fastdfs/storage:/fastdfs/storage -v /makeit/docker/fastdfs/client:/fastdfs/client -v /makeit/docker/fastdfs/conf/tracker.conf:/etc/fdfs/tracker.conf -v /makeit/docker/fastdfs/conf/storage.conf:/etc/fdfs/storage.conf -v /makeit/docker/fastdfs/conf/mod_fastdfs.conf:/etc/fdfs/mod_fastdfs.conf -v /makeit/docker/fastdfs/conf/client.conf:/etc/fdfs/client.conf -v /makeit/docker/fastdfs/conf/http.conf:/etc/fdfs/http.conf -v /makeit/web/fastdfs:/fastdfs/store --restart=always miitvip/nginx-fastdfs fastdf
用 docker ps 查看是否运行成功
[root@makeit build]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES41926f80d069 miitvip/nginx-fastdfs "/home/start.sh fast…" 4 minutes ago Up 4 minutes 80/tcp, 443/tcp, 0.0.0.0:8888->8888/tcp, 0.0.0.0:22122->22122/tcp, 9000/tcp, 0.0.0.0:23000->23000/tcp fastdfs5100677ead13 miitvip/nginx-fastdfs "/home/start.sh nginx" 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp, 8888/tcp, 9000/tcp, 22122/tcp, 0.0.0.0:443->443/tcp, 23000/tcp nginx
进入容器,查看通信状态。
# 进入容器[root@makeit /]# docker exec -it fastdfs /bin/bash # 查看 通信状态 # 看看 storage count / active count 相关信息bash-5.0# /usr/bin/fdfs_monitor /etc/fdfs/storage.conf[2019-07-26 04:28:27] DEBUG - base_path=/fastdfs/storage, connect_timeout=10, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0server_count=1, server_index=0tracker server is 你的Tracker服务器IP:22122group count: 1Group 1:group name = MIITVIPdisk total space = 40188 MBdisk free space = 22122 MBtrunk free space = 0 MBstorage server count = 1active server count = 1storage server port = 23000storage HTTP port = 8888store path count = 1subdir count per path = 256current write server index = 0current trunk file id = 0Storage 1:id = 你的Storage服务器IPip_addr = 139.159.151.94 (ecs-139-159-151-94.compute.hwclouds-dns.com) ACTIVEhttp domain = version = 5.12 ...... ...... # 后面还有吧啦啦一大串 ...
![eeaa8bd2744855ff001d2f9a1519e712.png](https://img-blog.csdnimg.cn/img_convert/eeaa8bd2744855ff001d2f9a1519e712.png)
上传测试
# 复制图片至容器中[root@makeit public]# docker cp logo.png 1195a55219ca:/home# 进入容器,并测试上传[root@makeit build]# docker exec -it fastdfs /bin/bashbash-5.0# cd /usr/bin/bash-5.0# ./fdfs_upload_file /etc/fdfs/client.conf /home/logo.png MIIT/M00/00/00/rBEACF0__qiAQR0zAAARuoXj0Jc992.png
![4277e2d057826074b199b26ea9ea61dd.png](https://img-blog.csdnimg.cn/img_convert/4277e2d057826074b199b26ea9ea61dd.png)
访问配置
我的 nginx 配置文件的映射目录在 /makeit/docker/nginx/conf.d 下,新建一个 file.conf 配置,内容如下:
server { listen 80; server_name file.makeit.vip; #charset koi8-r; #access_log /var/log/nginx/makeit/access.log main; access_log /var/log/nginx/file.access.log main; error_log /var/log/nginx/file.error.log warn; location / { root /www/fastdfs/data; index index.html index.htm index.php; autoindex on; } location /MIIT/M00 { rewrite ^/(.*) /$1 break; proxy_pass http://你的服务器IP:8888/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; 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 /www; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /.ht { deny all; }}
![b168783132b1e5299615a4932dba7a8f.png](https://img-blog.csdnimg.cn/img_convert/b168783132b1e5299615a4932dba7a8f.png)
最后说一下配置相关的一些字段信息,在配置过程中要注意修改。
# 配置中需要注意修改的地方# 在 docker run 时传参亦可# /etc/fdfs/tracker.confport=22122 # tracker服务器端口 ( 默认22122, 一般不修改 )base_path=/fastdfs/tracker # 存储日志和数据的根目录 ( 注意是 docker 内的目录 )# /etc/fdfs/storage.confport=23000 # storage服务端口 ( 默认23000, 一般不修改 )base_path=/fastdfs/storage # 数据和日志文件存储根目录store_path0=/fastdfs/store # 第一个存储目录tracker_server=192.168.52.1:22122 # tracker服务器IP和端口http.server_port=8888 # http访问文件的端口 ( 默认8888, 看情况修改, 和nginx中保持一致 )