技术解析

nginx 能不能不要这么先进?
0
2021-05-25 10:38:19
idczone
大带宽服务器我刚从 Apache 换到 nginx , nginx 是异步运行 php 的?
我用 @fpassthru($file);向用户传送文件,传送完成后我记录了这次传送成功了。
这样做在 Apache 下是没问题的,但是 nginx 好像是异步执行 php 的?文件还没有传输结束,就调用了 fpassthru 后面的语句,这样无法知道这次传输是否成功啊。
要怎么修改才能让 nginx 像 Apache 一样?
fpassthru 下面那句会执行就没 nginx 的事儿了, nginx 只是负责数据对传, 最多也就对传输数据加工一下, 运行 php 是后面 fpm 之类干的活儿, 不关 nginx 事儿, 你再 debug 下吧, 不过这种文件输出在 nginx 下用 X-Accel-Redirect 头比较好.

用 readfile 吧,然后刷缓冲区比较好。

是不是这样写:
@header('Content-Disposition: attachment; filename=' . $filename);
@header('Content-type: application/octet-stream');
@header('X-Accel-Redirect: ' . $filepath);
然后 fread/fpassthru/fclose 都不需要了?
浏览器出现 This webpage is not available ?能指导一下吗?

nginx 收到命令后是扔给 php-fpm 执行对吧?不管 php 脚本执行完后的结果?
不科学啊……
我的脚本分三部分:
1.写 sqlite 数据库:收到文件请求
2.用 fpassthru 传输文件
3.写 sqlite 数据库:发送文件完毕
Apache 运行是按 1->2->3 的顺序运行的
而 nginx 是按 1->3->2 ,有时甚至是 3->1->2 的顺序运行
是不是 nginx.conf ,或者 fastcgi 的配置问题?

你先用 apache+fcgi 试试。也有可能是 mod_php 和 php-fpm 的处理不同导致的。
1->3->2 是可能的,因为 nginx 有输出缓冲,文件不大的时候就是 132 。可以 X-Accel-Buffering no 但是性能估计会很惨。
3->1->2 我认为不可能,因为 fpassthru 传输完之前不会返回,这是 php 决定的。
X-Accel-Redirect 是给 uri 不是给文件名

https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/

应该是因为 nginx 是异步的吧。
你以为 Apache 用 100 个线程才能顶下来的压力, nginx 是怎么用 2 个线程就顶下来的……
nginx 会尽可能快地把后端的处理跑完(也就是 1->2->3 越快越好),然后关掉 php 的链接,再用 epoll 慢慢给客户发出去。如果你一定要同步处理的话,可以试试把输出缓冲设得特别小,强制 nginx 卡在那慢慢传送。
(没试过,纯粹拍脑袋。通常为了提高系统响应效率,都是想着后端死得越早越好,这样可以腾出 PHP 进程给其他请求。)

filepath 是完整路径吗?
不用 nginx 的 sendfile 改成 readfile 呢

是超时了吗?返回的是什么?

看到标题进来的,结果发现竟是吐槽

我建议你先把 @去掉, 让错误爆得明显一点, 现在这样不好判断.

Apache 也有问题了,好奇怪,我其它下载站可以的
新开个帖来讨论好了

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服