工作中几个场景涉及到文件上传,原来的解决方案是由tornado直接处理带文件(multipart-form)的http请求,但是文件有些文件过大,超过100M,再由tornado来处理有些不合适,stackoverflow有评论指出tornado把文件读到一个StringIO中,这样是有风险的,另外tornado只用来处理大文件上传也不是一个优雅的做法,这种事情还是有nginx来做的好,所以文件上传迁移到nginx upload module。
下载nginx upload module,截止到1月27,建议下载github上2.2分支的源码,我从其官网下载2.2.0版本源码编译时有问题,直接从github拖代码下来编译正常。
找到原来nginx所在路径,比如/usr/local/nginx,查看当前安装的编译参数:/usr/local/nginx/sbin/nginx -V,然后进入nginx源码目录,执行configure,除了加上已有的参数外,再加上:
--add-module=/path/to/upload/module
然后执行make && make install完成安装。
nginx upload module 配置
再nginx配置文件的server节点增加如下配置,假设http://hostname/upload地址用户文件上传。
location /upload { upload_pass /api/upload; upload_cleanup 400 404 499 500-505; upload_store /tmp/upload_tmp; upload_store_access user:r; upload_limit_rate 0; upload_set_form_field "file_name" $upload_file_name; upload_set_form_field "content_type" $upload_content_type; upload_set_form_field "tmp_path" $upload_tmp_path; upload_aggregate_form_field "md5" $upload_file_md5; upload_aggregate_form_field "size" $upload_file_size; upload_pass_form_field "^.*$"; }
基本配置如下:
upload_pass 指明了需要后续处理的php/tornado地址
upload_cleanup 如果php出现400 404 499 500-505之类的错误,则删除上传的文件
upload_store 上传文件存放地址
upload_store_access 上传文件的访问权限,user:r是指用户可读
upload_limit_rate 上传限速,如果设置为0则表示不限制
upload_set_form_field 设定额外的表单字段。这里有几个可用的变量:
$upload_file_name 文件原始名字
$upload_field_name 表单的name值
$upload_content_type 文件的类型
$upload_tmp_path 文件上传后的地址upload_aggregate_form_field 额外的变量,在上传成功后生成
$upload_file_md5 文件的MD5校验值
$upload_file_size 文件大小upload_pass_form_field 从表单原样转到后端的参数,可以正则表达式表示。官方的例子是upload_pass_form_field "^submit$|^description$";意思是把submit,description这两个字段也原样通过upload_pass传递到后端php处理。如果希望把所有的表单字段都传给后端可以用upload_pass_form_field "^.*$";
可以看到,我们上传文件存储到临时目录后nginx立即会向后面的tornado服务的/api/upload发起一个表单请求,其中有五个表单项:
这时就已经可以在tornado中对文件进行处理了。
代码如下:
def upload(self): file_name = self.get_argument("file_name") tmp_path = self.get_argument("tmp_path") do_some_thing(tmp_path) self.finish("file uploaded!")
-------------------2015-02-01-------------------
http://www.grid.net.ru/nginx/upload.en.html
Download sources from one of the links above. Unpack the archive:
tar xvzf nginx_upload_module-2.2.0.tar.gz
Configure nginx with additional module:
For nginx versions other than 0.7.44-51:cd <path to nginx sources> ./configure --add-module=<path to upload module sources> make make installFor nginx versions 0.7.44-51:
cd <path to nginx sources> CFLAGS="-Dnginx_version=7052" ./configure --add-module=<path to upload module sources> make make install