nginx+webpy配置灵活限速(python)

本文要求使用者具有基本的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;

比如/download?meidafile=test.flv&limit=1000&dir=meida 将被rewrite为/kbps?meidafile=test.flv&limit=1000&dir=meida

有些人在后面加上last,有些人在后面加上break,当然还有啥都不加的。

last表示:
    重新将rewrite后的地址在server标签中执行
break表示:
    将rewrite后的地址在当前location标签中执行
具体参见这个 博客
2,新的请求产生后,你必然是将其送至webpy去执行,这里借助于uwsgi,一切就跟普通访问一样了。

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用双引括起来,不然会被截断







你可能感兴趣的:(nginx+webpy配置灵活限速(python))