您好,欢迎访问一九零五行业门户网

加速PHP的ECHO[转]

作者: laruence本文地址: http://www.laruence.com/2011/02/13/1870.html 转载请注明出处
你也许注意到过, 在php中使用echo输出大段字符串的时候, 执行时间会明显的长, 也就会有朋友认为php的echo性能很差.
我在之前的文章中, 已经解释过了原因, 也希望能纠正”php的echo性能差”的这个误会.
然而之前的文章, 也仅仅是给出了原因, 并没有介绍如何避免这个问题, 在今天公司内的某个产品线(apache with php)发现了一个问题, 有用户在短时间内大量发起下载请求, 导致http连接数和数据库连接数剧增,
而数据库连接数剧增的原因是因为数据库的连接是单列模式, 一直到请求处理结束, 才会释放数据库链接. 这样就有了一个问题, 如果请求处理时间过长, 就会造成大量的数据库链接存在.
而这个用户的网速很慢, 这也就意味着, echo的”性能”很差~, 下载时间很长~. 如下图所示:
echo执行示意图
这也就引出了今天我要谈的这个问题, 如何让echo变快, 让php的请求处理过程, 尽快结束…
我们知道, 之所以echo慢, 是在等待”写数据”成功返回, 那么一个比较简单的办法, 就是打开输出缓存,
编辑php.ini
 output_buffering = 4096 //byte 当然, 你也可以在脚本中, 显示的调用ob_start():
ob_start(); echo $huge_string; //其他的逻辑. ob_end_flush(); 这里, 有一个要注意的地方, ob_start将会开辟一块4096大小的buffer, 所以, 如果huge_string大于4096, 将不会起到加速的作用.
现在, 我们的echo就会”立即”执行成功, 返回. 因为数据暂时写到了我们的输出缓存当中. 如果buffer足够大, 那么内容会等到脚本的最后, 才一次性发送给客户端(严格来说, 是发送给webserver).
但这样并不能解决我们今天遇到的这个问题, 因为这些数据到最后, 还是需要php去把它们发送给客户端(此时不考虑webserver的output buffer), 这个过程不结束, 请求不会关闭, php也不会执行db的析构函数~
那么, 既然做梦, 那就再做大点, 我们可以使用apache的输出缓存. 也就是改变成如下的执行流程:
加速echo示意图
假设, 我们的php要输出100k的数据, 那么, 我们apache的的输出缓存就必须大于100k, 否则当apache的输出缓存满了以后, 就会真正的发送给客户端, 而这个过程中, 当时执行的echo就会阻塞等待.
那么, 如何修改apache的输出缓存呢? 我们可以在apache的配置文件中, 使用sendbuffersize配置指令:
    sendbuffersize 4096 //注意是byt 具体的sendbuffersize的说明, 参看http://httpd.apache.org/docs/2.0/en/mod/mpm_common.html#sendbuffersize
注: 其他的webserver with php-cgi的模式, 请翻阅相关webserver的手册, 寻找类似配置.
现在, php的echo, 将直接把内容交给apache, php在执行完成后, 不再等待内容发送给客户端完成, 而直接退出. 而内容会在php处理完成以后, 由apache发送给客户端. 从而加速了echo的执行效率.
废话一句: printf, print, file_put_contents(“php://output”)…等等, 和echo都是一样的.
最后要说明, 这样做, 只是把原来echo的等待时间, 转移给了apache, 并没有真正的减少客户端获取到内容的时间. 它只是加速了php的处理过程, 提前了php的退出时机, 从而能减少php对资源的占用时间, 间接增加资源的占用率.
其它类似信息

推荐信息