我的设置: - nginx 1.0.6(从头开始编译) - php 5.3.8 带有 php-fpm(也是从头开始)。
我使用这个 PHP 脚本将文件从远程站点传输给我的用户:
$chunksize = 1 * (1024 * 1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'rb',false)) {
while(!feof($file) && (!connection_aborted()) && ($bytes_send<$new_length)) {
$buffer = fread($file, $chunksize);
echo ($buffer);
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else {
die('Error - can not open file.');
}
在我开始使用我的连接(20 Mbps)下载后,我得到了这样的 ifstat 结果
eth0
KB/s in KB/s out
5105.77 1925.70
5106.15 2063.77
5083.80 2337.95
4946.52 2487.28
5127.37 2507.15
5118.94 2474.98
5172.55 2438.86
4646.82 2451.87
5246.18 2465.98
5186.71 2459.66
5032.03 2458.55
这是正常的吗?由于带宽不足,生产服务器上的结果完全失败 :| 在 Apache 上平衡均匀。非常感谢帮助 :/
@Edit 做了一个小基准测试。通过这个下载 500 MB 文件。大约 250-260 MB 的结果就是这样,然后下降到几乎为 0。这是 nginx 的某种网络使用平衡吗?
答案1
发生这种情况的原因是 nginx 尝试尽可能快地从后端(在您的例子中是 php-fpm)读取,首先在内存中缓冲响应(受proxy_buffer_size
和proxy_buffers
设置限制),然后在磁盘上缓冲响应(最大为在中指定的大小proxy_max_temp_file_size
,默认值为 1 GiB)。因此,即使客户端下载速度较慢,您的“流式”脚本实际上也会尽可能快地下载文件。
查看nginx http 代理模块文档 — 有很多参数可以调整,大多数参数可以针对每个位置进行设置(因此您可以仅针对某些 URL 更改缓冲行为)。您甚至可以返回X-加速缓冲从后端的标头禁用缓冲,或者更好的是,返回X-Accel-重定向标头使 nginx 流式传输文件本身,而不绑定后端进程。