由于我们做的国外游戏运营业务,有大量的游戏文件,图片等资源都需要存储,而考虑到成本问题,我们都是自己买阿里云服务器,然后自己手工搭建文件存储服务,之前都是按教程安装,然后使用;后来我们为了安全,下载游戏链接防盗链,然后游戏下载链接都是动态生成,而且想做到游戏链接2分钟有效,所以必须自己在Nginx到FastDFS中有一个文件路径映射,并且在映射服务中可以自定义做一些逻辑校验,后来几经查找资料,才通过了解到可以利用Nginx的X-Accel-Redirect的响应头做服务内部跳转。目前已经上线了,而且运行良好,所以自己整理一下资料和自己的实践以备后续有用。
我们利用Fastdfs来作为APP和H5应用,图片存储服务系统,用于解决一下问题:
大量静态文件的存储和访问
将文件和数据服务分开存储
解决NAS存储单点问题
该系统主要分为三个模块
- CMS文件管理模块
一套基于HTML的UI界面的文件上传管理模块 - 文件映射模块
负责解析用户请求,利用X-Accel-Redirect响应头映射文件路径 - 文件存储模块
完全基于Fastdfs实现,易于扩展,要求安装fastdfs-nginx-module
文件映射模块介绍
映射模块基于Nginx内部原理实现,通过X-Accel-Redirect响应头进行Nginx内部跳转,所有在用户端浏览器是看不到该Header,所以不会暴露文件的真实地址,同时浏览器也不会做302跳转,是在一次请求中完成的。映射模块就是一个部署于Tomcat之上的web站点,其职责就是接受Nginx转发过来的请求,把URL地址转换为fastdfs存储物理地址,并返回给Nginx,Nginx拿到物理地址后读取文件并返回给用户。
Nginx作为高性能的反向代理服务器,在本模块中起到的作用不仅仅是负载均衡,还利用到了Nginx的一个内部特性sendfile,利用该特性,Tomcat作为映射模块仅需要处理映射关系,而不用处理文件IO操作,而我们知道,应用程序服务器上的性能瓶颈往往是IO操作,通过部署这样的系统结构,得以提高系统的整体性能。
映射模块工作流程
Nginx(负载均衡和读取文件的作用)
Tomcat站点(处理URL和物理地址对应关系和权限程序逻辑)
MySql(存储URL和文件物理地址关系存储)
文件路径解析流程步骤
- Nginx作为负载均衡,接受用户请求,并将请求转发到某个Tomcat实例上。
- Tomcat 通过查询本地缓存,得到物理地址,并将物理地址写入Response Header中,其key为:X-Accel-Redirect。
- Nginx获取到Response Header中包含X-Accel-Redirect,读取其中的value,并再次将请求分发到fastdfs-nginx-module上。
- fastdfs-nginx-module返回数据给Nginx,用户接收到文件流,整体流程结束。
Nginx配置
WEB站点转发规则配置
location / {
proxy_pass http://192.168.0.11:28085/; #首先pass到应用服务器
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
Nginx文件处理规则
location /app/M00 {
charset utf-8;
internal; (表示这个只做Nginx内部处理)
expires -1s;
ngx_fastdfs_module;
#proxy_pass http://192.168.0.11:38088;
}