前言
要接手闪电的项目,就先从拆出来的 api
项目看起了,在看的过程中,看到了一个之前没有用过的函数 fastcgi_finish_request
,便尝试了解了一下。
fastcgi_finish_request 的能力
鸟哥在 2011 年写了一篇关于 fastcgi_finish_request
的文章 《使用fastcgi_finish_request提高页面响应速度》,里面介绍了 fastcgi_finish_request
可以加速 响应速度,事实也是如此。
在看文章评论时,发现了 achun
说的一个问题 (做了简易修改,主要是为了语句通顺):
实际应用中发现一个问题:
使用 fastcgi_finish_request 后,
如果脚本执行时间长,在执行结束之前,触发此事件的机器,无论切换浏览器,再也打不开执行相同 php(唯一入口)的页面了,直到脚本执行完成才行,被阻塞了。
具体环境:nginx+php 5.4
脚本中 fastcgi_finish_request 后,是执行curl的大量循环。但是服务器肯定是运行好好的,如果不是访问那个唯一入口 php,或者换一台机器就没有阻塞问题。
浏览器返回的错误是网管错误。
思考与尝试
思考
fastcgi_finish_request
虽然能够加速页面响应速度,但是由于程序可能有后续处理,会占用 php-fpm
的一个进程,那么当某一个请求被分配到这个请求上时,就必须等待其结束,这可能造成阻塞,也就是上面 achun
所说的现象。
尝试
先将 php-fpm
的进程调为一个,不调也可以,多试几次就好。
写了一个代码,如下:
<?php
echo 'hello world;'. PHP_EOL;
fastcgi_finish_request();
sleep(10000);
第一次访问,页面响应速度很快,直接输出 hello world
。
第二次访问,等待许久,页面报 504
错误。在相同环境下的网站都出现了 504
错误。
说明
上述的例子是有点极端,这也仅仅是说明 fastcgi_finish_request
后续的操作会阻塞后续 php
的请求。
最后
fastcgi_finish_request
的能力是非常好的,用的好,会让用户体验提升,但也要注意后续的处理,可能会造成表象和内在的不一致,造成问题排查的困难。
-- EOF --
本文转载自IMJCW