msgbartop
PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 – 左手代码 右手诗
msgbarbottom

13 Apr 11 使用fastcgi_finish_request提高页面响应速度

当PHP运行在FastCGI模式时,PHP FPM提供了一个名为fastcgi_finish_request的方法.按照文档上的说法,此方法可以提高请求的处理速度,如果有些处理可以在页面生成完后再进行,就可以使用这个方法.

听起来可能有些茫然,我们通过几个例子来说明一下:

<?php

echo '例子:';
fastcgi_finish_request(); /* 响应完成, 关闭连接 */

/* 记录日志 */
file_put_contents('log.txt', '生存还是毁灭,这是个问题.');
?>

通过浏览器访问此脚本, 结果发现并没有输出相应的字符串,但却生成了相应的文件.由此说明在调用fastcgi_finish_request后,客户端响应就已经结束,但与此同时服务端脚本却继续运行!

合理利用这个特性可以大大提升用户体验,趁热打铁再来一个例子:

<?php

echo '例子:';

file_put_contents('log.txt', date('Y-m-d H:i:s') . " 上传视频\n", FILE_APPEND);

fastcgi_finish_request();

sleep(1);
file_put_contents('log.txt', date('Y-m-d H:i:s') . " 转换格式\n", FILE_APPEND);

sleep(1);
file_put_contents('log.txt', date('Y-m-d H:i:s') . " 提取图片\n", FILE_APPEND);

?>

代码里用sleep模拟一些耗时的操作,浏览时没有被堵塞,程序却都执行了,具体看日志.

末了给您提个醒,Yahoo在Best Practices for Speeding Up Your Web Site中提到了Flush the Buffer Early,也就是利用PHP中的flush方法把内容尽快发到客户端去,它和本文介绍的fastcgi_finish_request有些许的类似.

转载附言: 我看了下这个方法, 在调用的时候, 会发送响应, 关闭连接. 但是不会结束PHP的运行. 相比调用flush, 或者我之前介绍的加速你的Echo来说, 这个方法能更加干脆一些.

另外, 从代码的可移植性讲的话, 可以在代码中附上如下代码:

if (!function_exists("fastcgi_finish_request")) {
      function fastcgi_finish_request()  {
      }
}

不会造成代码部署在非fpm环境下造成问题.


分享到:



Random Posts:

Tags:

20 Responses to “使用fastcgi_finish_request提高页面响应速度”

  1. Duron |

    max_execution_time会影响它的执行吗?

  2. bigbol |

    这个和 comet 用途有什么区别?

  3. 1031 exchange |

    It’s going to be ending of mine day, but before ending I am
    reading this fantastic paragraph to increase my experience.

    Look at my web-site … 1031 exchange

  4. achun |

    我用独立的php 文件
    简单写了个

    sleep 150
    <?php
    echo fastcgi_finish_request();
    set_time_limit(0);
    sleep(150);
    exit;

    却没有阻塞的情况,应该是唯一入口中某种情况造成的,但是是什么呢???

  5. achun |

    哦。刚才又测试了下 直接用 sleep 进行延时
    问题依旧,不过这次换浏览器不阻塞了
    偶尔同一个浏览器会有响应
    阻塞超时返回的是 504 Gateway Time-out

  6. achun |

    实际应用中发现一个问题
    fastcgi_finish_request 后
    如果脚本执行时间长,在执行结束之前,触发此事件的机器,无论切换浏览器,再也打不开执行相同php(唯一入口)的页面了,直到脚本执行完成才行,被阻塞了
    具体环境
    nginx+php 5.4
    脚本中 fastcgi_finish_request 后,是执行curl的大量循环。

    但是服务器肯定是运行好好的,如果不是访问那个唯一入口php,或者换一台机器就没有阻塞问题

    浏览器返回的错误是网管错误

  7. warpig's blog » 【转】使用fastcgi_finish_request提高页面响应速度 |

    [...] 本文地址: http://www.laruence.com/2011/04/13/1991.html [...]

  8. PHP5.4的新特性 — 见贤思齐 |

    [...] 使用fastcgi_finish_request提高页面响应速度 [...]

  9. 雪候鸟 |

    @nroe 用__destruct干啥呢?

  10. nroe |

    为啥不用 public function __destruct() ?

  11. htf |

    不错啊,很有帮助,不过Mod_php不能使用。
    fastcgi_finish_request之后的代码,虽然不占Web服务器时间,快速响应。后边的代码还是要占用fastcgi进程的时间。可以用异步事件模式。将请求插入到高速消息队列中,然后在守护进程中完成。
    http://www.swoole.com/news/55.html

  12. Thinking In LAMP Blog » Blog Archive » PHP每月通讯(2011年5月) |

    [...] http://www.laruence.com/2011/04/13/1991.html   使用fastcgi_finish_request提高页面响应速度 [...]

  13. lotte |

    很不错的学习资料,能在自己网站上尝试。或许能少走不少歪路。

  14. fy |

    @CFC4N 你的这个例子应该使用异步处理来完成:)
    这步应该做异步队列的插入,而不是连接smtp。。。

  15. winting |

    那如何知道程序执行完?

  16. wintng |

    这样一下,像登录的话,可能涉及很多复杂的东西可以我们可以放在”伪后台执行(fastcgi_finish_request)”,
    但是如果数量多的话, 就会出现超时的现象, 可以在头部加入set_time_limit(0);

  17. PHP在FastCGI模式时用fastcgi_finish_request提高页面响应速度 | SEO 4 IT - Website Creater |

    [...] 2011/04/13, ryan writes: 嗯,尽量早的flush,我也觉得很好,facebook的pagelet模式我已经开始用了,感觉不错~~~ [...]

  18. 怪物宝 |

    很不错啊,受教

  19. ryan |

    嗯,尽量早的flush,我也觉得很好,facebook的pagelet模式我已经开始用了,感觉不错~~~

  20. CFC4N |

    这确实是太好了,这个优点可以用于那些长时间执行的代码转为”后台执行”。类似制造了一个“任务中间层”去执行这些耗时的操作,比如用户找回密码的时候,可以直接返回找回成功,后台连接SMTP发送邮件,连接SMTP所耗时完全不需要用户等待返回,可先告诉用户已经完成,提高用户体验。

Leave a Reply

*