五、PHP性能改进在生产中的实践
5.1、XHProf
首先来看一下XHProf这个工具,怎么能改进我们的PHP语言本身。
首先安装这个工具,就是模块化安装。
我们封装一下操作类。
<?php
/**
* 优才网公开课示例代码
*
* XHProf 封装类
*
* @author 伍星
* @see http://www.ucai.cn
*/
class XHProf
{
public function __construct()
{
// start profiling
$XHPROF_ROOT = "/home/wwwroot/ucai_app/samples";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";
}
public function beginProf()
{
xhprof_enable();
register_shutdown_function('XHProf::endProf');
}
public function endProf()
{
$xhprof_data = xhprof_disable();
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");
echo "<a href=\"http://samples.app.ucai.cn/xhprof_html/index.php?run=$run_id&source=xhprof_foo\">性能分析结果</a>";
}
}
值得注意的是这句话:
register_shutdown_function('XHProf::endProf');
什么意思呢,就是在整个页面完成了之后,输出结果报表链接。
5.2 、Opcache的安装与配置
其次我们来看看 opcache,安装过程没有什么讲的,主要是推荐一个配置,并且需要强调,opcache不是PHP extension,是zend extension, 所以非常容易出错。配置如下:
[opcache]
zend_extension="/usr/local/php/lib/php/extensions/no-debug-zts-20090626/opcache.so"
opcache.enable_cli=1
opcache.memory_consumption=128 //共享内存大小, 这个根据你们的需求可调
opcache.interned_strings_buffer=8 //interned string的内存大小, 也可调
opcache.max_accelerated_files=4000 //最大缓存的文件数目
opcache.revalidate_freq=60 //60s检查一次文件更新
opcache.fast_shutdown=1 //打开快速关闭, 打开这个在PHP Request Shutdown的时候
// 会收内存的速度会提高
opcache.save_comments=0 //不保存文件/函数的注释
5.3、Yaf和Phalcon
再次来看两个C语言写的PHP框架
第一个介绍的是Yaf 框架,这是一个纯C语言框架。具体的安装过程和实验如下:
1、从github 下载 php-yaf https://github.com/laruence/php-yaf
2、解压,按PHP模块的编译手法编译
phpize
./configure --with-php- /usr/local/php/bin/php-config
make
make install
3、在php.ini 中配置
extension = "yaf.so"
yaf.environ="product"
4、通过命令行上执行 php –m|grep yaf 你就能看到模块已经安装好了。
5、余下的就是Web测试。
在源码目录下,找到
php-yaf-master/tools/cg
./yaf_cg ucai_gkk
6、将output 目录下的 ucai_gkk 移至 samples.app.ucai.cn 所在的目录下,就可以通过 http://samples.app.ucai.cn/ucai_gkk
来访问。
7、我们可以做一下改造实验,了解一下这个框架的基本结构。
大家可以看到,我只是一通过一个工具,就生成了整个程序的框架,就可以根据需要,添加自己的业务逻辑。
比如 ,在models/Sample.php 中增加一个方法,
public function selectProductSample()
{
return "<h1>Hello Haha</h1>";
}
在 views 目录下新建文件,product/index.phtml
<?php
/**
* 优才网公开课示例代码
*
* Yaf 视图
*
* @author 伍星
* @see http://www.ucai.cn
*/
echo $content, " I am ", $name, " From Product";
?>
在controllers 目录下建立 Product.php
<?php
/**
* 优才网公开课示例代码
*
* Yaf 控制器
*
* @author 伍星
* @see http://www.ucai.cn
*/
/**
* @name IndexController
* @author root
* @desc 默认控制器
* @see http://www.php.net/manual/en/class.yaf-controller-abstract.php
*/
class ProductController extends Yaf_Controller_Abstract
{
/**
* 默认动作
* Yaf支持直接把Yaf_Request_Abstract::getParam()得到的同名参数作为Action的形参
* 对于如下的例子, 当访问http://yourhost/hello/index/index/index/name/root 的时候, 你就会发现不同
*/
public function indexAction($name = "Product")
{
//1. fetch query
$get = $this->getRequest()->getQuery("get", "default value");
//2. fetch model
$model = new SampleModel();
//3. assign
$this->getView()->assign("content", $model->selectProductSample());
$this->getView()->assign("name", $name);
//4. render by Yaf, 如果这里返回FALSE, Yaf将不会调用自动视图引擎Render模板
return TRUE;
}
}
这样我们就可以通过,http://samples.app.ucai.cn/hello/?a=index&c=product,这样的链接来访问,我们新建的内容了。操作起来很简单。
用同样的方式,我们安装Phalcon。虽然从形式上,它更简单。通过目录就知道,内容更为丰富。
这也是Yaf跟Phalcon的很大的不同之处,Yaf尽管效率很高,但是要在生产上使用,还是略显单薄,功能不够丰富。而Phalcon则真的是功能很全的。正像优才网培养的叫全栈工程师,而Phalcon也号称自己是Full Stack 的一个框架。
这次,没有工具来生成一个基本的框架,但是我们可以从Github上的一个教程,作为切入点。
https://github.com/phalcon/tutorial
下载了这个教程之后,我们就可以开始动手了。先看看功能 。
放到相应的目录下之后,比如 http://samples.app.ucai.cn 目录下之后,得配置一下rewrite 规则。
rewrite ^/phalcon/(.*?)$ /phalcon/public/index.php?_url=/$1 last;
rewrite ^/phalcon$ /phalcon/public/index.php last;
然后,通过 http://samples.app.ucai.cn/phalcon/ 可以访问。
发现有一个注册功能,那我们就来想这个数据怎么保存的。
发现在 public/index.php 中有一段配置,
//Set the database service
$di->set('db', function() {
return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
"host" => "127.0.0.1",
"username" => "xxxx",
"password" => "xxxxx",
"dbname" => "xxxxxx"
));
});
我们在这里改了配置了之后,再看看提交的情况。
发现在SignupControll.php 中有一段保存代码 ,
$user = new Users();
$user->name = $name;
$user->email = $email;
//Store and check for errors
if (($userid = $user->save()) == true)
{
echo 'Thanks for register!';
} else
{
echo 'Sorry, the next problems were generated: ';
foreach ($user->getMessages() as $message)
{
echo $message->getMessage(), '<br/>';
}
}
过去看这个 models/Users.php 却是空的?
我们在不修改Users.php的时候,看看是否能将数据保存进去?
当然前提是建一个表,因为我怀疑,这存在某种关系 的映射。
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(70) NOT NULL,
`email` varchar(70) NOT NULL,
PRIMARY KEY (`id`)
);
发现果不其然,保存进去了,好,我们再进一步,找一现实中可能会用的表格格式,比如下划线的表格 users_exinfo。
CREATE TABLE `users_exinfo` (
`id` int(10) unsigned NOT NULL default 0,
`schoolname` varchar(70) NOT NULL,
`age` int NOT NULL,
PRIMARY KEY (`id`)
);
看看能否实现保存,于是乎也建了一个空类。
class UsersExinfo extends Phalcon\Mvc\Model{
}
同时也修改了视图,将数据保存了进去。
结果如下:
大家看到,成功地保存了数据。
5.4、zephir高效开发模块
好的,讲到这里,衍生出一个小话题,就是开发模块。
在PHP里,开发模块,是一个很痛苦的过程。因为C语言,大家都知道,是出了名的难学的,值得高兴的是,也是Phalcon这个团队的童鞋们,也为我们准备了一个高效的开发模块的语言,称之为zephir。正因为扩展如此难以开发,但是扩展又是如此高效,所以我们要用高效的方式来开发扩展。
git clone https://github.com/phalcon/zephir.git
cd zephir/
mv zephir /usr/local/
然后就可以开发模块了,我们使用
zephir init gkk
生成模块的框架,
然后 cd gkk/gkk
编写 hello.zep
namespace Gkk;
/**
* This is a sample class
*/
class Welcome
{
/**
* This is a sample method
*/
public function welcome()
{
echo "你们好!参加优才网公开课的同学们!";
}
public function say()
{
echo "今天是优才网第三十三讲公开课了!";
}
}
然后再返回
zephir compile
zephir build
然后在 php.ini 中配置
extension=gkk.so
通过 php –m 可以看到相应的模块。再编写
test.php
<?php
$t = new Gkk\Welcome();
$t->say();
echo "\n";
?>
就能看到相应的输出。
5.5、各框架性能总结
好的,有关两个用C开发的框架和相关内容我们就介绍到这里。下面我们来总结一下框架,以及做一些性能评测。
首先来看一下性能评测报告,这是一个专门测框架的github项目出的数据,
博客在这里,
•https://github.com/eryx/php-framework-benchmark
从上面的图可以看到,两个用C编写的框架,性能还是相当可观的。Yaf比Phalcon性能更强,也不奇怪。因为结构更为简单,模块更少。同时也发现,像zend framework这样的框架,是不能轻易在一个大众的互联网产品中使用的,尽管代码写得不错,但是效率太低了,有木有!
5.6、PHP的重写
在评测之前,大家记起来了没有,我们上面讲了六点,其中有一点是什么?重写PHP!
那就看看,哪些业界人士,在PHP重写的路子上做了非常激动人心的尝试。
刚才讲了,谁最有动力?有两个方面的人有动力,一个是PHP最大的使用者,一个是PHP官方。最大的使用者,他对PHP的提升,能大幅度地减少资源的占用,一个百分之几的优化可能就是成百上千台设备的节省。而后者,则要想到如果PHP本身效率提升不上去,在未来的发展过程中,很容易出现转折,尽管现在还是非常火的。
所有从官方,就有了,PHPng,这个我没有安装过,有兴趣的同学,可以自己去折腾,https://wiki.php.net/phpng 值得一提的是,咱们国内的鸟哥是这个项目的主要参与者之一。Yaf也是他的作品。而另外一个,则是Facebook主导的,HHVM,其前身是HipHop, 当时的思路是把PHP全部编译成C++程序,在上线的过程中,上线的是一个二进制包,非常不灵活,修改代码,需要发包才能生效。如果出现故障,会有灾难性的影响。所以演进到现在成了HHVM,全称是HipHop Virtual Machine。
现在的模式,简单了讲就是可以做为FastCGI 的运行容器。大家安装过LNMP的同学就知道,在Nginx的后端,也就是说Nginx的配置中,通过fastcgi_pass 这个配置指向了实际运行PHP的FastCGI 运行容器,PHP自带的是PHP-FPM(FastCGI Process Manager),而HHVM就是可以一定程度上无缝地替换掉,FPM,比如你kill掉FPM进程,通过
hhvm --mode server -vServer.Type=fastcgi -vServer.Port=9000 &来启动HHVM。都不需要修改nginx 配置。就可以访问了。但是性能一定程度上,大有提升。
这枚神器有如下特点:
•当然不是小团队能玩的
•与PHP 5.2引擎+APC相比,可以处理的Web请求吞吐量增加了9倍,而内存消耗减少了5倍。
•如无特殊模块,可以无缝替换 php-fpm(除了极少数兼容问题)
•1、优点
–FB出品
–强大到令你吃惊,数十倍的性能提升
–已经趋于稳定,无缝替换 PHP-FPM
•2、缺点
–还不是很稳定
–模块需要迁移
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。