求下载站的附件下载解决方案
直奔主题,如下,求各位看官帮助
背景:
本人为业余站长,将本行业工作需要的资料收集整理出来做了个下载站,目前每天下载流量在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、若以上方案不行,建议采用什么方案呢?
感谢大家百忙之中帮我解答,由于本人是业余站长(平常工作完全与互联网无关),所以技术水平有限,希望大家能帮帮忙,谢谢大家!
Answers
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");