本文要求使用者具有基本的Nginx+webpy+uwsgi使用经验。
nginx限速的话题google上可以搜索到很多,这里暂时不讨论固定限速的情况,即使用limit_rate 和limit_rate_after 设置,这个很简单。
这里讨论根据http头自由限速,google上基本只有php和rails的例子,并且这些例子全部来自于官方wiki关于xsendfile部分,以及页脚部分给出的例子
Using X-Accel-Redirect Header With Nginx to Implement Controlled Downloads (with rails and php examples)
还有热心网友根据此文翻译的中文。
本文描述webpy框架下,即Python语言的实施情况。
这里面有四个关键点,一是要限速的资源必须是有Internal标识,即只能由nginx内部请求访问,不能由外部请求访问;二是,内部请求的访问,必须加上
x-accel-redirect头用于重定向,加上x-accel-limit-rate,用于标识速度,加上x-accel-charset:utf-8 标识字符编码,三是,所有的请求必然是来自于外界,
要想把这个请求转换为内部请求,则要通过rewrite转换,四是,如何加http头,官方的例子是php的,并且可以直接执行Php,那是因为它在系统中有php环境,
nginx肯定不能直接执行php,这个误导了我很长时间,因为我仿效这种做法,总是执行不了Python,也不知道该用那些类去加http头。实际上真的很简单,
就是rewrite到一个url,借助于uwsgi,在webpy中实现这个url对应的http头操作即可。然后返回。
了解思路之后,直接上代码
1,原始请求必然不是直接访问这个媒体资源。我们假设是download目录,那么你第一步是要将这个URL通过rewrite转换为内部请求。
rewrite ^/download /kbps?$args last;
有些人在后面加上last,有些人在后面加上break,当然还有啥都不加的。
3,webpy中实现/kbps对于的类,
4,重定向到meida资源,实现http头限速
代码合并如下:
nginx配置代码如下:
server{ location / { rewrite ^/download /kbps?$args last; uwsgi_pass 127.0.0.1:9000; include uwsgi_params; # index indexjw.html index.htm;; uwsgi_param UWSGI_CHDIR /usr/local/nginx/html; uwsgi_param UWSGI_SCRIPT webheader; root html; } location /media/{ root html; internal; } }webpy的python代码如下,假设文件名为webheader.py
import web urls=( '/kbps','kpbs' ) app = web.application(urls, globals()) class kpbs: def GET(self): inputstr=web.input() limit=inputstr.limit newstr='/media/'+inputstr.file print 'this is kpbs' web.header('X-Accel-Limit-Rate',limit) web.header('X-Accel-Charset', 'utf-8') web.header('X-Accel-Redirect', newstr) return web if __name__ == "__main__": print "main" app.run() else : application=app.wsgifunc()
uwsgi执行命令如下
/uwsgi -s 127.0.0.1:9000 -w webheader.py
调试时,及时查看nginx的log,包括access.log和error.log也有助于调试。
我喜欢用wget测试,对于有词典结构的URL,要URL用双引括起来,不然会被截断