一、回顾fastDFS
- 是余庆写的一种分布式文件系统框架,该框架包含3个角色
- 追踪器
- 存储节点
- 客户端
- 如果存储节点集群要扩容,应该增加一个新组来放新主机
- 启动
fdfs_trackerd /etc/fdfs/tracker.conf fdfs_storaged /etc/fdfs/storage.conf
- 上传下载
# 上传 fdfs_upload_file /etc/fdfs/client.conf 要上传的文件 # 下载 fdfs_download_file 客户端的配置文件(/etc/fdfs/client.conf) 上传成功之后得到的字符串(fileID)
二、上传流程
- 客户端将文件上传到nginx服务器
- nginx将该请求转发到fastcgi进程
- fastcgi将数据暂时写入磁盘,然后上传到fastDFS的存储节点上
- 上传成功得到fileID、存储节点的IP、Port都上传到数据库保存
三、下载流程
- 客户端的 http请求 发送到 下图中间的Nginx服务器,服务器将请求转发给fastcgi进程
- fastcgi进程查询数据库后 返回 数据所在的存储节点IP、Port
- 客户端直接把http请求发送该IP、Port的存储节点
- 存储节点上安装了nginx,和nginx上的fastDFS插件,因此nginx可以和存储节点通信
- 存储节点将 http请求 交给nginx来解析
- nginx将解析结果交给存储节点,存储节点取出对应文件交由nginx发送给客户端
四、安装fastdfs-nginx插件
1. 下载:wget https://sourceforge.net/projects/fastdfs/files/FastDFS%20Nginx%20Module%20Source%20Code/fastdfs-nginx-module_v1.16.tar.gz
2. 在nginx源码目录中执行./configue,但要像下面这样加上参数--add-module=插件的src目录
root@100ask:/home/book/Downloads/nginx-1.10.1# ./configure --add-module=/home/book/Downloads/fastdfs-nginx-module/src
3. make报错 fatal error: fdfs_define.h: No such file or directory, 以及找不到common_define.h
在/home/book/Downloads/nginx-1.10.1/objs/Makefile 中 加两行 -I
ALL_INCS = -I src/core \
-I src/event \
-I src/event/modules \
-I src/os/unix \
-I /usr/local/include/fastdfs \
-I /usr/local/include/fastcommon/ \
-I objs \
-I src/http \
-I src/http/modules\
-I /usr/include/fastdfs/ \
-I /usr/include/fastcommon/
4.发现启动后没有worker进程,没能正常运行起来
root@100ask:/usr/local/nginx/sbin# ./nginx
root@100ask:/usr/local/nginx/sbin# ps aux|grep nginx
root 7780 0.0 0.0 37892 656 ? Ss 03:26 0:00 nginx: master process ./nginx
root 7794 0.0 0.0 14432 1044 pts/0 S+ 03:26 0:00 grep --color=auto nginx
5.查看/usr/local/nginx/logs/error.log 找原因
[2023-07-28 03:26:00] ERROR - file: shared_func.c, line: 968, file /etc/fdfs/mod_fastdfs.conf not exist
[2023-07-28 03:26:00] ERROR - file: /home/book/Downloads/fastdfs-nginx-module/src/common.c, line: 155, load conf file "/etc/fdfs/mod_fastdfs.conf" fail, ret code: 2
即:shared_func.c加载mod_fastdfs.conf配置文件时找不到
实际上在~/Downloads/fastdfs-nginx-module/src目录下,需要将其复制过来
6.此外,还需要修改一下mod_fastdfs.conf配置文件(和storage.conf的配置保持一样)
# 存储log日志的目录
base_path=/home/book/yxfastdfs/storage
# 连接tracker地址信息
tracker_server=192.168.232.132:22122
# 存储节点绑定的端口
storage_server_port=23000
# 当前存储节点所属的组
group_name=group1
# 客户端下载文件的时候, 这个下载的url中是不是包含组的名字
# 上传的fileID: group1/M00/00/00/wKj3h1vJRPeAA9KEAAAIZMjR0rI076.cpp
# 完整的url: http://192.168.1.100/group1/M00/00/00/wKj3h1vJRPeAA9KEAAAIZMjR0rI076.cpp
# 即想要实现:通过http://存储节点IP/fileID 这个url就能下载文件,
# 如果只有1组,那么url不需要groupname,否则需要把下面的这个选项设为true
url_have_group_name = true
# 存储节点上存储路径的个数
store_path_count=1
# 存储路径的详细信息
store_path0=/home/robin/fastdfs/storage
7. 启动仍然没有worker进程,再次看error.log
[2023-07-28 04:13:42] ERROR - file: ini_file_reader.c, line: 631, include file "http.conf" not exists, line: "#include http.conf"
[2023-07-28 04:13:42] ERROR - file: /home/book/Downloads/fastdfs-nginx-module/src/common.c, line: 155, load conf file "/etc/fdfs/mod_fastdfs.conf" fail, ret code: 2
即:/etc/fdfs下找不到http.conf这个文件,实际上在~/code/fastdfs-5.10/conf目录下。拷贝过来即可
[2023-07-28 04:30:24] ERROR - file: shared_func.c, line: 968, file /etc/fdfs/mime.types not exist
即:shared_func.c代码的第968行找文件mime.types没找到,实际上在/home/book/Downloads/nginx-1.10.1/conf/目录下。同样拷贝过来
五、实际使用
想要实现:浏览器通过http://存储节点IP/fileID 这个url就能下载文件
- 先上传一张图
book@100ask:~/Downloads$ fdfs_upload_file /etc/fdfs/client.conf 1.jpg group1/M00/00/00/wKjohGTDg3eAQx09ADYDn-wridU777.jpg
- 浏览器访问 http://192.168.232.132/group1/M00/00/00/wKjohGTDg3eAQx09ADYDn-wridU777.jpg
报错信息: open() "/usr/local/nginx/zyFile2/group1/M00/00/00/wKjohGTDg3eAQx09ADYDn-wridU777.jpg" failed (2: No such file or directory), client: 192.168.232.1, server: localhost, request: "GET /group1/M00/00/00/wKjohGTDg3eAQx09ADYDn-wridU777.jpg HTTP/1.1", host: "192.168.232.132"
- 由上可知服务器找文件找错位置了,必须写location来告诉服务器正确位置 - M00是一个映射路径,需要映射到/home/book/yxfastdfs/storage/data, 后面的/00/00/是真实路径。因此root要写至data目录,而不是只写至storage目录 这里的命令为/group1/M00/00/00/,但后面的00/00/变数很大,不可能一个个去配置,因此下面写的模糊匹配。实际上group1和M00也会变,可以用正则表达式来写。
location /group1/M00/ { root /home/book/yxfastdfs/storage/data; ngx_fastdfs_module; }
- 使用关键字ngx_fastdfs_module,表示在nginx服务器上增加一个进程,用于和本地fastDFS的存储节点通信,至于怎么通信的不用管。
总结使用流程:
文件下载:
浏览器作为客户端,在访问http://192.168.232.132/group1/M00/00/00/wKjohGTDg3eAQx09ADYDn-wridU777.jpg时,将命令发送到了nginx服务器(注意,这是原来的存储节点上安装了带插件的nginx)80端口,命令匹配/group1/M00/。此前已经启动了存储节点,且在mod_fastdfs.conf配置文件中已经写好了存储节点的端口号与IP地址,因此nginx先解析http请求(也就是找location),然后ngx_fastdfs_module模块创建一个进程与存储节点通信拿到文件,nginx再将文件发送给客户端。在此下载过程中,没有使用fastDFS的追踪器,因为不需要由它来获知存储节点的IP、Port。
文件上传:
客户端将文件作为post请求的请求体发送给nginx服务器,nginx服务器解析该http请求后无法处理,就由FastCGI进程管理器创建一个fastcgi进程来处理,fastcgi会先向fastDFS追踪器询问存储节点的IP、Port,然后其中已经被重定向的printf函数将文件写入存储节点,得到fileID,最后会将fileID以及对应的文件名上传到数据库服务器中。