• C++文件服务器项目—Nginx+FastDFS插件—5


    前言

      本文介绍了Nginx+FastDFS插件的安装流程以及文件上传下载的流程。文件安装包、源码地址:gopherWxf git

      本专栏知识点是通过零声教育的线上课学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接 C/C++后台高级服务器课程介绍 详细查看课程的服务。

    1. 文件上传下载流程

    1.1 文件上传流程

    在这里插入图片描述
    文件上传流程:

    1. 客户端发送上传文件请求
    2. nginx只能处理静态请求,所以调用fastCGI
    3. fastCGI程序读取数据,临时存储到本地磁盘
    4. fastCGi程序将文件上传到fastDFS,返回fileID
    5. 将文件名,和返回fileID等信息存储到数据库(业务逻辑细节不做展开,后续介绍)
    6. 删除本地的临时文件

    1.2 文件下载流程

    在这里插入图片描述

    文件下载流程:

    1. 客户端发送下载文件请求
    2. nginx只能处理静态请求,所以调用fastCGI
    3. fastCGI程序从数据库中获得对应的fileID
    4. fastCGI程序从fastDFS通过fileID下载文件
    5. 将文件回发给客户端
    6. 删除磁盘的临时文件

    1.3 文件下载优化流程

    在这里插入图片描述

      如果下载能够直接让客户端连接fastDFS的存储节点, 实现文件下载,那么下载的流程就非常简单了。

    # 举个例子
    http://192.168.109.100/group1/M00/00/00/wKj3k1tMBKuARhwBAAvea_OGt2M471.jpg
    
    • 1
    • 2

      想要实现这个优化有几个问题需要解决:

    1. 客户端发送请求使用的协议:http。而fastDFS不能解析http协议
      • nginx能解析http协议。
      • nginx和fdfs是两个独立的进程,互不干涉
      • 在存储节点上安装一个nginx,让nginx帮助它解析http请求
      • 收到之后把数据发送给nginx,nginx再把数据发送给客户端
      • 这里的小nginx就相当于中转
      • 中转就要求nginx和storage能够进行数据交互
      • 在nginx中安装fastDFS的插件
    2. 客户端怎么知道文件存储在哪个存储节点storage上?
      • 上传的时候存储过<文件名,fileID>
      • 通过nginx服务器查询并返回该信息。

    在这里插入图片描述

    文件下载优化流程

    1. 客户端发送下载请求
    2. nginx服务器去数据库查询fileID以及是哪台storage存储数据,组装url发回给客户端
    3. 客户端通过URL访问fastDFS
    4. fastDFS通过Nginx和插件,将数据回发
    5. 客户端完成下载

    2. Nginx和fastDFS插件

    2.1 安装Nginx和fastdfs-nginx-module插件

    1. 所有的存储节点上安装Nginx, 将软件安装包拷贝到fastDFS存储节点对应的主机上。注意了,一定是存储节点,至于原因在上面优化流程以及说过了。文件压缩包在前言中。
    # 1. 找fastDFS的存储节点
    # 2. 在存储节点对应的主机上安装Nginx, 安装的时候需要一并将插件(fastdfs-nginx-module)装上
    #	- (余庆提供插件的代码   +   nginx的源代码 ) * 交叉编译 = Nginx  
    
    • 1
    • 2
    • 3
    1. 在存储节点对应的主机上安装Nginx, 作为web服务器
    root@wxf:/source_code_dir# tar zxvf nginx-1.16.1.tar.gz
    root@wxf:/source_code_dir# tar zxvf fastdfs-nginx-module-1.22.tar.gz
    root@wxf:/source_code_dir# cd fastdfs-nginx-module-1.22/
    root@wxf:/source_code_dir/fastdfs-nginx-module-1.22# vi INSTALL
    
    • 1
    • 2
    • 3
    • 4

      这里面告诉我们在安装nginx的时候,要带上fastdfs-nginx-module/src目录,然后再安装
    在这里插入图片描述

    # 1. 进入nginx的源码安装目录
    # 2. 检测环境, 生成makefile
    # ./configure --add-module=fastdfs插件的源码目录/src
    # make
    # sudo make install
    root@wxf:/source_code_dir# cd nginx-1.16.1/
    root@wxf:/source_code_dir/nginx-1.16.1# ./configure --add-module=/source_code_dir/fastdfs-nginx-module-1.22/src
    root@wxf:/source_code_dir/nginx-1.16.1# make
    root@wxf:/source_code_dir/nginx-1.16.1# make install
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.2 解决Nginx无法正常启动的问题

    1. 安装成功, 启动Nginx, 发现没有 worker进程

    没有work进程

    root@wxf:/usr/local/nginx/conf# nginx 
    root@wxf:/usr/local/nginx/conf# ps aux |grep nginx
    root       8948  0.0  0.0  33180   472 ?        Ss   14:22   0:00 nginx: master process nginx
    root       9156  0.0  0.0  13140  1104 pts/1    S+   14:25   0:00 grep --color=auto nginx
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    找nginx的logs日志
    在这里插入图片描述
    提示:file /etc/fdfs/mod_fastdfs.conf not exist

    # ERROR - file: shared_func.c, line: 1301, file /etc/fdfs/mod_fastdfs.conf not exist
    # 从哪儿找 -> fastDFS插件目录中找
    root@wxf:/source_code_dir/fastdfs-nginx-module-1.22/src# tree 
    .
    ├── common.c
    ├── common.h
    ├── config
    ├── mod_fastdfs.conf
    └── ngx_http_fastdfs_module.c
    
    root@wxf:/source_code_dir/fastdfs-nginx-module-1.22/src# cp mod_fastdfs.conf /etc/fdfs
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    root@wxf:/etc/fdfs# ls
    client.conf     mime.types.back   storage.conf      tracker.conf storage_ids.conf
    
    • 1
    • 2

      需要修改mod_fdfs.conf文件, 参数按照当前存储节点的storage.conf进行修改。storage.conf里面怎么配置,mod_fdfs.conf就怎么配置。

    # 存储log日志的目录
    base_path=/fastdfs/storage
    # 连接tracker地址信息
    tracker_server=192.168.109.101:22122
    # 存储节点绑定的端口
    storage_server_port=23000
    # 当前存储节点所属的组
    group_name=group1
    
    # 客户端下载文件的时候, 这个下载的url中是不是包含组的名字
    # 上传的fileID: group1/M00/00/00/wKj3h1vJRPeAA9KEAAAIZMjR0rI076.cpp
    # 完整的url: http://192.168.109.101/group1/M00/00/00/wKj3h1vJRPeAA9KEAAAIZMjR0rI076.cpp
    url_have_group_name = true
    
    # 存储节点上存储路径的个数
    store_path_count=1
    # 存储路径的详细信息
    store_path0=/fastdfs/storage
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1. 重启启动Nginx, 还是没有worker进程, 查看log日志
    # ERROR - file: ini_file_reader.c, line: 1051, include file "http.conf" not exists, line: "#include http.conf"
    从 /etc/fdfs 下找的时候不存在
    	- 从fastDFS源码安装目录找/conf
    	- sudo cp http.conf /etc/fdfs
    # ERROR - file: shared_func.c, line: 1301, file /etc/fdfs/mime.types not exist
    从 /etc/fdfs 下找的时候不存在
    	- 从fastDFS源码安装目录找/conf
    	- sudo cp mime.types /etc/fdfs
    
    root@wxf:/source_code_dir/fastdfs/conf# cp mime.types /etc/fdfs/
    root@wxf:/source_code_dir/fastdfs/conf# cp http.conf /etc/fdfs/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

      现在nginx是正常的启动了
    在这里插入图片描述

    2.3 通过URL下载文件: 404 Not Found

    # 上传一张gopher的照片
    root@wxf:/temp# fdfs_upload_file /etc/fdfs/client.conf gopher.png 
    group1/M00/00/00/wKhtZWMaAlyAD9WYAABR1ZotbJI570.png
    
    • 1
    • 2
    • 3

    通过浏览器请求服务器下载文件: 404 Not Found在这里插入图片描述

    查看一下error日志,发现是路径不对,需要配置location

    # http://192.168.109.101/group1/M00/00/00/wKhtZWMaAlyAD9WYAABR1ZotbJI570.png
    2022/09/08 14:56:02 [error] 9415#0: *1 
    open() "/usr/local/nginx/html/group1/M00/00/00/wKhtZWMaAlyAD9WYAABR1ZotbJI570.png" 
    failed (2: No such file or directory), 
    client: 192.168.109.1, server: localhost, 
    request: "GET /group1/M00/00/00/wKhtZWMaAlyAD9WYAABR1ZotbJI570.png HTTP/1.1", 
    host: "192.168.109.101"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    http://192.168.109.101/group1/M00/00/00/wKhtZWMaAlyAD9WYAABR1ZotbJI570.png
    # 错误信息
    open() "/usr/local/nginx/html/group1/M00/00/00/wKhtZWMaAlyAD9WYAABR1ZotbJI570.png" failed (2: No such file or directory), client: 192.168.109.1, server: localhost, request: "GET /group1/M00/00/00/wKhtZWMaAlyAD9WYAABR1ZotbJI570.png HTTP/1.1", host: "192.168.109.101"
    
    
    # /usr/local/nginx/html/group1/M00/00/00/wKhtZWMaAlyAD9WYAABR1ZotbJI570.png
    服务器在查找资源时候, 找的位置不对,所以找不到
    
    需要给服务器指定一个正确的位置, 如何指定?
    	- 资源在哪? 在存储节点的存储目录中 store_path0
    	- 如何告诉服务器资源在这? 在服务器端添加location处理
    
    按照之前文章介绍的指令查找方法,可以可以把指令提取出来
    - location /group1/M00/00/00/
    
    但是后面的两个目录00/00/,有很多个,而且文件存储的时候是随机存的
    - 难道我们要写这么多个location?
    - location采用的是模糊匹配
    - 所以我们直接把指令缩短
    - location /group1/M00/
    
    location /group1/M00/
    {
    	# 告诉服务器资源的位置store_path0
    	root /home/robin/fastdfs/storage/data;
    	ngx_fastdfs_module;
    }
    
    在分布式里面,可能有多个group,多个目录Mxx
    - 难道还要把所有的可能都枚举写出来吗
    - 用正则即可
    location ~/group([0-9])/M([0-9])([0-9]) {
    	# 告诉服务器资源的位置store_path0
    	# 这个root真的正确吗?
    	root /home/robin/fastdfs/storage/data;
    	ngx_fastdfs_module;
    }
    
    上面也说了,可能有多个目录,也就意味着store_path可能有多个,
    那root要与location的指令对应,指令都用正则了,root怎么写?
    - 不用写,ngx_fastdfs_module会帮我们处理
    - 上文我们以及配置过mod_fastdfs.conf
    - 会从这里面找资源存储的位置
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

      在/usr/local/nginx/conf/nginx.conf中配置location
    在这里插入图片描述

      可以看到我们上传的图片被下载下来了。这里被浏览器显示图片的原因是谷歌浏览器会自动打开图片。

    在这里插入图片描述

    在这里插入图片描述

    3. 上传大文件Nginx设置

    1. 413 错误

      服务器提示:413 Request Entity Too Large 的解决方法

      • 原因: 上传文件太大, 请求实体太长了

      • 解决方案:

        • 在配置文件nginx.conf中添加: client_max_body_size 10M
          • xxxM: 用户指定的大小多少兆(M)
    2. 设置的位置:

      • 在http{ }中设置:client_max_body_size 20m;

        • 所有的server中的所有的location都起作用
      • 在server{ }中设置:client_max_body_size 20m;

        • 对当前server的所有的location生效
      • 在location{ }中设置:client_max_body_size 20m;

        • 只对当前location生效
    3. 三者的区别是:

      • http{} 中控制着所有nginx收到的 http 请求。

      • 报文大小限制设置在server{}中,控制该server收到的请求报文大小

      • 如果配置在location中,则报文大小限制,只对匹配了location 路由规则的请求生效。

    在这里插入图片描述

  • 相关阅读:
    给出一个用二维矩阵表示的图像返回该图像顺时针旋转90度的结果扩展:你能使用原地算法解决这个问题么?
    Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
    Java msyql批量插入 十万条数据
    爱上开源之boot4go-dockerui-剧透篇
    23种设计模式-原型设计模式介绍加实战代码
    LangGPT作者教你编写高质量提示词
    普罗米修斯
    103.192.211.X怎么设置一台服务器跳转到第三方服务器上访问
    笔试强训48天——day24
    【Selenium】提高测试&爬虫效率:Selenium与多线程的完美结合
  • 原文地址:https://blog.csdn.net/qq_42956653/article/details/126772169