X

fastcgi_finish_request函数的妙用以及性能测试

昨天无意中得知 fastcgi_finish_request这个函数以及对应的register_shutdown_function,然后对他做了一个了解,用他可以实现一些非常巧妙而有趣的事情。首先,我们看下这个函数的注解:

special function to finish request and flush all data while continuing to do something time-consuming (video converting, stats processing etc.);

它能够让你结束你跟浏览器的交互,然后在后台再继续的运行这个线程,做一些不需要输出,不需要和浏览器交互的事情,例如,上传视频后,视频在转码的时候,不需要用户等待,可以先告诉用户成功,然后再到后台转码(优酷是不是这样? 视频传成功以后,还需要等段时间,才能后台看到该视频的信息。,我们直接通过程序来说明吧。

test.php

$pid = getmygid();
var_dump($pid);
while(1) {
sleep(1);
file_put_contents("./data", $pid, FILE_APPEND);
 }

在浏览器中打开上面一段程序,显然不会有任何输出,而且程序会一直运行,表现为,浏览器在转啊转,直到超时,当然,如果你打开后,关闭了浏览器,这等一会,程序也自动结束了。

如果,我们稍微改一下:

$pid = getmypid();
var_dump($pid);
fastcgi_finish_request();
while(1) {
sleep(1);
file_put_contents("./data", $pid, FILE_APPEND);
 }

这一次他很快的返回了结果,然后,我们去后台看看去,通过文件的写入,发现程序还在运行,然后执行 ps aux | grep php

longan    3448 26.8  0.7  40544  3596 ?        R    23:32   0:22 php-fpm: pool www

发现给出的进程号一直存在的,说明了其实是给nginx发送了信号,中断了与nginx的连接,然而进程其实还是同一个进程,继续运行,所以上面的数据,都可以继承下来。

接下来,我对系统进行了改造,因为系统有写日志的动作,我将这一行为放到了页面渲染之后,并且加上了fastcgi_finish_request(),后面费时的操作越多,将越收益。

实际的测试结果,当没有使用fastcgi_finish_request()这个函数的时候,使用100个并发, 机器基本上被打满,cpu到了100,全部是阻塞状态下:

而使用了中断的方式以后:

有一点点的降低,然后,我们使用并发5来测试,此时机器的负载大概在50%左右,

没有使用中断前:

使用中断以后:

 

降低肯定是有所降低的,但是由于我这里只有一个error_log操作,所以获利不多,不过在有些场景下,则是相当有用的,大家不妨考虑一下.

hope this can help you !

Categories: PHP编程
龙安_任天兵: 不忘初心,方得始终!