nginx文件上传限速
https://github.com/cfsego/limit_upload_rate 这个模块,通过修改nginx核心源码,可以支持设置文件上传限速
首先下载 nginx-1.2.6 稳定版本
解压后目录结构如下
在局域网环境下我发现如果文件在60s内没有上传完毕,服务器会丢弃此连接,需要配置client_body_timeout为一个更大的值
默认值是60s。(nginx官方手册对这个参数的介绍如下)
“Defines a timeout for reading client request body. A timeout is only set between two successive read operations, not for the transmission of the whole request body. If a client does not transmit anything within this time, the client error 408 (Request Time-out) is returned.”
大概看了一下这个模块对限速的实现,通过对连接的write事件添加定时器,降低服务器的数据处理能力(其实这时客户端已经把全部数据发送给服务端了的),间接影响read事件就会超时。或者做下面的处理,每次延迟write事件的时候重置read事件的超时(添加下面注释的三行即可)
首先下载 nginx-1.2.6 稳定版本
解压后目录结构如下
$ ls for-nginx.patch nginx — addon — limit_upload_rate — src — ...执行 patch -p0 < for-nginx.patch将补丁替换源代码
./configure --without-http_gzip_module --add-module=./addon/limit_upload_rate-master make配置nginx.conf
location ~ .*.php$ { limit_upload_rate 500k; limit_upload_rate_after 1m; fastcgi_index index.php; fastcgi_pass unix:/usr/local/ciaos/php_fcgi.socket; include /usr/local/ciaos/fastcgi.conf; }测试文件upload.html
<html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <form enctype="multipart/form-data" action="up.php" method="POST"> <!-- Name of input element determines name in $_FILES array --> Send file: <input name="Filedata" id="Filedata" type="file" /> <input name="submit" type="submit" value="Send File" /> </form> </body> </html>上传处理up.php
<?php // Define a destination $targetFolder = "/files"; // Relative to the root if (!empty($_FILES)) { $tempFile = $_FILES["Filedata"]["tmp_name"]; $targetPath = $_SERVER["DOCUMENT_ROOT"] . $targetFolder; $targetFile = rtrim($targetPath,"/") . "/" . $_FILES["Filedata"]["name"]; if (file_exists($tempFile)) { move_uploaded_file($tempFile,$targetFile); //move_uploaded_file($tempFile,$targetFile); echo "Upload succeed"; } else { echo "Invalid file type."; } } ?>记得修改files目录的权限为777,最后可以用chrome浏览器测试了,文件上传达到限速效果。
在局域网环境下我发现如果文件在60s内没有上传完毕,服务器会丢弃此连接,需要配置client_body_timeout为一个更大的值
默认值是60s。(nginx官方手册对这个参数的介绍如下)
“Defines a timeout for reading client request body. A timeout is only set between two successive read operations, not for the transmission of the whole request body. If a client does not transmit anything within this time, the client error 408 (Request Time-out) is returned.”
大概看了一下这个模块对限速的实现,通过对连接的write事件添加定时器,降低服务器的数据处理能力(其实这时客户端已经把全部数据发送给服务端了的),间接影响read事件就会超时。或者做下面的处理,每次延迟write事件的时候重置read事件的超时(添加下面注释的三行即可)
ngx_http_limit_upload_input_body_filter(ngx_http_request_t *r, ngx_buf_t *buf) { off_t excess; ngx_int_t rc; ngx_msec_t delay; ngx_http_limit_upload_ctx_t *ctx; ngx_http_limit_upload_conf_t *llcf; // add line below // ngx_http_core_loc_conf_t *clcf; rc = ngx_http_next_input_body_filter(r, buf); if (rc != NGX_OK) { return rc; } ctx = ngx_http_get_module_ctx(r, ngx_http_limit_upload_module); llcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_upload_module); if (ctx->limit_rate == 0) { ctx->limit_rate = llcf->limit_rate; } if (ctx->limit_rate) { ctx->received += ngx_buf_size(buf); excess = ctx->received - llcf->limit_rate_after - ctx->limit_rate * (ngx_time() - r->start_sec + 1); ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "limit upload: ctx=%p, received=%O, " "excess=%O, limit_rate=%z, period=%M", ctx, ctx->received, excess, ctx->limit_rate, ngx_time() - r->start_sec + 1); if (excess > 0) { if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } delay = excess * 1000 / ctx->limit_rate; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "limit upload: delay=%M", delay); ctx->read_event_handler = r->read_event_handler; ctx->write_event_handler = r->write_event_handler; r->read_event_handler = ngx_http_test_reading; r->write_event_handler = ngx_http_limit_req_delay; ngx_add_timer(r->connection->write, delay); // add two lines below // clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); // ngx_add_timer(r->connection->read, clcf->client_body_timeout); return NGX_AGAIN; } } return NGX_OK; }此外还有一个文件上传模块可做参考; nginx_upload_module
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。