求下载站的附件下载解决方案

直奔主题,如下,求各位看官帮助

背景:
本人为业余站长,将本行业工作需要的资料收集整理出来做了个下载站,目前每天下载流量在30G~50G左右。网站采用WordPress(别吐槽,本来也没打算做大,只是比较熟悉,方便我二次开发而已),原来的附件都是使用第三方云存储(至于哪家就不广告了,国内就那几家),附件主要以50M以下的pdf、rar文件为主。
云存储成本太高,受不了了。。。。

需求:
拟自己搭建附件服务器,并绑定独立二级域名
文件通过http直接访问真实地址http://download.xxxx.com/xxxxx.pdf(即在网页点击后可以直接下载)
文件防盗链

实施步骤:
服务器环境拟为Centos6.4+lighttpd+Proftpd,安装ftp主要是为了批量上传附件
开启lighttpd的x-sendfile
lighttpd设置refer防盗链,只能通过我网站点击才能下载(更高级的防盗链方式暂时没搞过)
使用ftp工具将第三方云存储的文件批量下载下来,然后批量将附件上传至自己搭建的附件服务器
在网站的MySql数据库中用SQL统一替换掉原来的下载url

问题:
1、使用lighttpd做为附件服务器的方案是否可行?nginx呢?
2、如何设置每个下载线程的下载速度?
3、lighttpd做附件下载服务器,50个人同时下载,大致消耗多少内存?
4、lighttpd如何限制为单线程下载(防止使用迅雷等工具把带宽榨干了)
5、该方案存在的问题
6、如果不采用独服,是否可以采用20刀/月的linode来做附件下载(配置:2 GB RAM,2 CPU Cores,48 GB SSD Storage,3 TB Transfer,40 Gbit Network In,250 Mbit Network Out)?
7、若以上方案不行,建议采用什么方案呢?

感谢大家百忙之中帮我解答,由于本人是业余站长(平常工作完全与互联网无关),所以技术水平有限,希望大家能帮帮忙,谢谢大家!

阅读 11.7k
5 个回答

自己摸索已经搞定了,目前已经上线测试
防盗链使用的nginx第三方模块,非cookie方式认证,可防迅雷,简单实用

教程写在博客里了:
传送门《nginx做静态文件下载服务器之安装与配置
2015-9-14补充:
最终采用的是lighttpd,主要是限速模块和防盗链模块功能更完善,只需要简单配置即可,
最主要的是可以对下载链接设置有效期

根据实际使用来看,也更加稳定,也许做静态文件服务器还是应该lighttpd是目前最合适的
图片描述

图片描述

图片描述

Nginx可以用limit_rate进行限速,用X-Accel-Redirect头使用Sendfile机制发送文件,可以用AIO线程池发送大文件.

http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate

location /download/ {
    limit_rate_after 500k;
    limit_rate 50k;
}

大概意思是:用户下载达到500k后,便控制其速度在50k以内.

http://nginx.org/en/docs/http/ngx_http_core_module.html#aio
Nginx从1.7.11开始为AIO引入了线程池支持,能够使用多线程读取和发送文件,以免工人进程被阻塞.要启用多线程支持,configure时需要显式加入--with-threads选项.启用aio时会自动启用directio,小于directio定义的大小的文件则采用sendfile进行发送,超过或等于directio定义的大小的文件,将采用aio线程池进行发送,也就是说aio和directio适合大文件下载.

location /download/ {
    sendfile on;
    sendfile_max_chunk 256k; 
    aio threads;
    directio 512k;
    output_buffers 1 128k;
}

sendfile_max_chunk可以减少阻塞调用sendfile()所花费的最长时间.因为Nginx不会尝试一次将整个文件发送出去,而是每次发送大小为256KB的块数据.

Nginx X-Accel-Redirect: 经过PHP身份验证后把文件交给Nginx输出.

<?php
auth(); //用户身份认证
header('Content-type: application/octet-stream'); //如果是图片可以这样header('Content-type: image/png');
header('Content-Disposition: attachment; filename="'.basename($file_path).'"'); //提示下载附件
//下面直接通过PHP输出文件
//readfile($file_path);
//对比PHP通过X-Accel-Redirect告诉Nginx文件的路径
//Nginx通过sendfile机制读取文件并发送给浏览器
header("X-Accel-Redirect: $file_path");

上传到百度云盘啥的,然后把地址换成分享链接,这样你就不用搭服务器了

1.文件数
2.每月总流量
3.每日最高流量

如果你不是做这方面的,最好交给第三方来做,比如国内的七牛,又拍,这并不是上传上去就不用管了,比如你知道文件系统的inode是什么吗,这可能是你碰到的第一个问题了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏