• 各开源框架使用与设计总结


        

    一、框架课程总结


        框架、设计模式和队列是5月份公开课的三个主题,第一周讲设计模式,第二、四周讲框架,第三周讲队列。框架讲了两周,介绍了框架的概念、PHP框架的应用范围,以及常用的PHP框架,今天是框架的最后一讲,是对整个框架系列课程的汇总,同时和大家讨论一些框架之外、或者框架之下的技术。

        今天要讨论的分为这几个方面,总结框架系列课程、探讨框架可能存在,或者解决不了的问题,以及其解决方案和当前的探索。

    在框架第一讲中,志华老师也站得高度很高,讲述了框架、架构的概念,以及对比了它的异同。总结来讲就是架构涉及到的是一个产品的性能、可扩展性之类问题。而框架则涉及到一个产品在实际的实现过程之中,所用的技术方案。比如性能和可扩展性,也就是架构所关系的内容,和底层语言其实关系不大。无论是PHP语言,还是Ruby语言,来实现一个大型网站,后端都可以部署数据库,数据库有主从,都需要缓存,缓存都可以是Memcached,数据库可以是MySQL。而框架则是我们做一个产品实现所用的具体技术实现方案,不但跟语言本身关系密切,而且涉及到在开发中的具体开发方案。打一个比喻,建造一个开发区。架构就是图纸,水、电、暖布局、楼盘、商业布局、容量布局,而框架则是细化的实施方案,这个写字楼是板楼还是塔楼,是做写字楼还是做酒店,前者与材料外观无关,后者则与材料外观相关。

    再在后面的课程中,我们分别了解了Durpal、Symfony、ThinkPHP、YII、ZendFramework等框架的用法与扩展。

         

    通过对框架的学习,我们认识到各自的框架都有自己的优势,使用框架带来了巨大的便利,比如很快构建起一个脚手架,英文叫Skeleton,有很多可用的方便工具和函数。当然,学习一套框架有成本,使用一套框架更有约束。也能看到框架的作用,可以归结为如下几点:

    1、快速构建的脚手架,而不是从零开始

    2、一套共同的约束和规则,保证开发质量。

    3、工具和函数库、共同认识,无疑提高了开发效率

     

    二、跳出PHP应用开发框架看框架

    但是?今天我们从两个层次来看讨论问题。

    第一个层次是高级的层次,我们简单看一下。在前面讲的,都基于PHP的应用开发框架而展开,即使我们讲了这么些框架,但这些框架也只是小部分代表,如果只站在应用的这个层次再多讨论也没有太大的意义。我们要跳出来看,就像,框架就是在应用开发这个层次吗?就只讨论PHP语言吗?他们的共同特点在哪里?

    框架并不是局限于某个特定语言、或者特定用途东西。比如我们讲Web 开发框架,这个Web开发框架,可以是PHP的,也可以是Ruby语言写的,像Rubyon rails,甚至最近流近的 go 语言,也开始有自己的Web开发框架,甚至还有用 C语言去写的。而框架也不仅限于Web开发或者网站功能开发,有测试框架,像PhpUnit,JUnit这样的软件。像Thrift、ICE这样的,属于分布式通信框架。

    共同特点,有几点:

    1、都提供了自己领域内较完整强大的功能。(区别于函数库,比函数库更综合,更完整)。

    2、都提供了自己领域内功能较具体的实现。(区别于架构这个较虚的概念)。

    3、但是提供的是一些规范、脚手架。(区别于现成的产品,这只是一个特定领域的半成品)。

     

    三、框架可能或者带来的问题

    了解了框架在整个编程开发领域,大面上的感性认识,我们具体来探讨这两周公开课下来,框架所不能解决的问题。这是第二个层次,是更深入的层次。

    1、第一个问题,就是开发习惯上的问题。如果团队决定采用一个框架。特别是全新的框架,就比较费劲了,可能还得有一个正式的培训阶段。

    2、第二个问题,框架都有其适用的场景,需要架构师需要在什么阶段在合适的时候,采用合适的框架。

    3、第三个问题,性能问题。大部分的框架,都用到了一些复杂的规则,比如ORM、比如模板引擎,这些东西,天生就是比较低效,尤其是像PHP这样的动态脚本语言。在企业系统、小流量的时候,还好,但是如果进入大流量时期,这个性能问题,就不容忽视了。

    4、第四个问题,是扩展性问题。比如流量大了,数据库后端,也不再是一个数据库了,同一个数据类型也不再是一个数据表了。这个时候,框架有些地方,就该动动了。ThinkPHP那一讲上分享了这样的问题。

     

    四、PHP性能的改进手段

    好的,那我们来看一下,PHP业界,在提高框架性能、或者者整个PHP性能问题上,所做的一些探索。这也是我们今天的重点。

    那么,我们想一想,你想提高PHP程序的效率,可以做哪些尝试?另外还有一个意思的事情是,你觉得,谁对提高 PHP程序的效率,最有动力?

    第一、我们知道,PHP很容易写出很低效的程序,数据库频繁重连。写的查询很低效。某个函数实现,可能有问题等等。那么这些问题,需要有一个很好的手段去发现。这个时候,一个神器诞生了。这就是XHProf。XHProf是谁出的呢?Facebook,这是我们刚才讲的谁最有动力来提高PHP效率呢,谁在大规模的环境下,经常使用PHP,就最有动力。Facebook就最有这个动力了。

    第二、上面讲的是第一个层次,先把PHP语言本身的一些东西给优化了。把第一个层次应用到框架上,就是我们通过XHprof可能发现了框架的一些性能瓶颈。第二个层次呢?我们再反问一下,提高程序性能最有效的方式是什么?我相信大部分同学都会提一个手段,缓存。没有错,第二个提升的层次就是缓存,我们将模板编译,是一种缓存方式,或者在库中,支持一些外部缓存,比如ThinkPHP 就是一个很典型的例子,支持模板编译缓存。也支持大量预置的Cache函数库。

    第三个层次,有人就想了,PHP这种动态的脚本语言,在每一次运行时都是现编译解析,有没有一些办法,把这个每次编译解析的过程省了。这其实也经过了两个步骤。在CGI时代,每一个PHP页面的运行,所有的PHP模块都需要重新加载。每一个程序都有这个加载过程其实很浪费的。

    因此就进入了mod_php 这个阶段,就是这张图

    而再到后来改进成这张图,

    再到后来,人们从PHP本身的编译过程上再省一步,加进了opcache,就是opcode 的cache,就是从PHP脚本编译成为操作码的缓存,这样的话,对程序,省去了第一个编译环节。

    就成了这一张图

    上面虚线的部分,就是缓存住了的,一个脚本只执行一次编译,后面的调用,都共享第一次编译所留下来的opcode缓存,APC就是一个实现opcode缓存的框架,同类的还有XCache,eAccelerator,我们今天的例子是用的zend opcache。

    上面说了这么多,这还只是第三个层次,其实还有三个层次的手段。

    第四个层次,是将核心的,有瓶颈的业务逻辑,转到后端去实现。也就是说不用PHP了,举一个典型的例子,就是分库分表,连接池这样的功能,当然,分库分表,我们可以采用PHP来实现,但是连接池这样的功能就比较费劲一些了。所以一般对于一个高效的分布式架构来讲,这种逻辑会有一个DB Proxy,来管理着客户端对服务器的长连接,PHP本身不再直接连接数据库,而是连接这个代理,由这个代理,来实现多表查询等操作。这里只是举一个例子。比如我们讲的缓存,甚至KVDB、全文检索,估计也有朋友写过PHP版存储和引擎,但是实际上在现实的使用中,还是更多的使用后端的服务。

    第五个层次,就是一些大神出来了,他们受不了传统PHP,PHP框架的低效,开发模块,开发模块化的PHP框架。这个比较好理解。模块嘛,C语言实现,编译成二进制共享库,从Web Server一启动就预加载。所以必然会高效一截。今天我们来看看Yaf、Phalcon这两C写的框架。也正好呼应咱们框架总结的这个主题。

    第六个层次,我就该来问了?是不是PHP本身也是非常陈旧和低效了,是不是有改进的空间,甚至PHP重新用不一样的思路实现,可行不可行?这个问题,后面慢慢道来。

    好的,是不是感觉有了一种全新的视角?我们回过来看看这些改进,在实际生产中的实现。

    五、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 PhalconDbAdapterPdoMysql(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 PhalconMvcModel{
    
       
    
    }
    

      

    同时也修改了视图,将数据保存了进去。

    结果如下:

    大家看到,成功地保存了数据。

    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 GkkWelcome();
    
    $t->say();
    
    echo "
    ";
    
    ?>
    

      

    就能看到相应的输出。

    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、缺点

    –还不是很稳定

    –模块需要迁移

    六、各项实践,性能评测

    下面进入性能评测,评测我们相对就比较快速一些。直接用ab命令,来测试上面的所提及的一些改进。

    以下评测,所有测试页面,均为:http://hjvote.app.ucai.cn/index.php 命令行为:

    ab -c 20 -n 1000 http://hjvote.app.ucai.cn/index.php

    6.1 、冷启动

    1、冷启动,比如我新启动的php-fpm,关掉opcache,关掉xhprof

    Concurrency Level:      20
    
    Time taken for tests:   4.981 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      478000 bytes
    
    HTML transferred:       109000 bytes
    
    Requests per second:    200.78 [#/sec] (mean)
    
    Time per request:       99.612 [ms] (mean)
    
    Time per request:       4.981 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          93.72 [Kbytes/sec] received
    

      

    6.2、第二次

    2、第二次,条件同上。

    Concurrency Level:      20
    
    Time taken for tests:   4.537 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      478000 bytes
    
    HTML transferred:       109000 bytes
    
    Requests per second:    220.42 [#/sec] (mean)
    
    Time per request:       90.736 [ms] (mean)
    
    Time per request:       4.537 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          102.89 [Kbytes/sec] received
    

      

    6.3、打开opcache第一次

    Concurrency Level:      20
    
    Time taken for tests:   1.591 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      478000 bytes
    
    HTML transferred:       109000 bytes
    
    Requests per second:    628.67 [#/sec] (mean)
    
    Time per request:       31.813 [ms] (mean)
    
    Time per request:       1.591 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          293.46 [Kbytes/sec] received
    

      

    6.4、第二次,条件同上

    Concurrency Level:      20
    
    Time taken for tests:   1.254 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      478000 bytes
    
    HTML transferred:       109000 bytes
    
    Requests per second:    797.70 [#/sec] (mean)
    
    Time per request:       25.072 [ms] (mean)
    
    Time per request:       1.254 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          372.36 [Kbytes/sec] received
    

      

    6.5、对比再打开xhprof

    Concurrency Level:      20
    
    Time taken for tests:   1.254 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      478000 bytes
    
    HTML transferred:       109000 bytes
    
    Requests per second:    797.44 [#/sec] (mean)
    
    Time per request:       25.080 [ms] (mean)
    
    Time per request:       1.254 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          372.24 [Kbytes/sec] received
    

      

    6.6、打开XHprof,关掉Opcache

     对于这个简单的页面,没有明显恶化,我们去掉Opcache,打开xhprof

    Concurrency Level:      20
    
    Time taken for tests:   12.103 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      595000 bytes
    
    HTML transferred:       226000 bytes
    
    Requests per second:    82.62 [#/sec] (mean)
    
    Time per request:       242.065 [ms] (mean)
    
    Time per request:       12.103 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          48.01 [Kbytes/sec] received
    

      

    6.7、第二次、条件同上

    Concurrency Level:      20
    
    Time taken for tests:   9.298 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      595000 bytes
    
    HTML transferred:       226000 bytes
    
    Requests per second:    107.55 [#/sec] (mean)
    
    Time per request:       185.952 [ms] (mean)
    
    Time per request:       9.298 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          62.50 [Kbytes/sec] received
    

      

    在没有opcache的情况下,XHProf的加入,导致用户急剧变慢。

    6.8、关掉xhprof  HHVM第一次

    Concurrency Level:      20
    
    Time taken for tests:   1.142 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      521000 bytes
    
    HTML transferred:       109000 bytes
    
    Requests per second:    875.84 [#/sec] (mean)
    
    Time per request:       22.835 [ms] (mean)
    
    Time per request:       1.142 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          445.62 [Kbytes/sec] received
    

      

    6.9、 第二次,条件同上

    Concurrency Level:      20
    
    Time taken for tests:   0.852 seconds
    
    Complete requests:      1000
    
    Failed requests:        0
    
    Write errors:           0
    
    Total transferred:      521000 bytes
    
    HTML transferred:       109000 bytes
    
    Requests per second:    1173.42 [#/sec] (mean)
    
    Time per request:       17.044 [ms] (mean)
    
    Time per request:       0.852 [ms] (mean, across all concurrent requests)
    
    Transfer rate:          597.03 [Kbytes/sec] received
    

      

    什么感觉?这种数字的差距是不是可以用震撼来形容?通过评测对比,我们对于opcache、hhvm和一般php-fpm性能心里也就有数了。同时也发现,在页面上开启XHProf,会导致网页性能急剧下降,所以不要在生产环境对多人开启XHProf。或者会带来非常不好的用户体验。

    七、自有框架的设计

    好的,看完了性能评测,我们来过了一下如果设计一个自有的框架需要哪些元素,或者说需要哪些内容。

    1、首先对目录结构进行一个划分,确定目录层次结构

    –app    命令行应用

    –data   存放数据上传

    –lib 库函数

    –template  模板

    –conf   各种配置

    –doc    文档,SQL

    –log     日志

    –test    测试代码

    –ctemplate 编译后的模板

    –htdocs     Web主目录

    大家能看到,htdocs 同其他目录,比如 doc、app目录为什么要并列?这是安全性的考虑,想一想,否则的话,你的表定义被人下走了。你的后台程序,可能会被用户执行。

    2、其次来看一下类的层次结构。

    下图是应用程序各个类的分层。

    最基层的应用程序类,其实就是一个骨架。包括了getParam(取得参数,无论命令行,还是Web访问,都需要有参数分析)。checkParam(参数检测)、checkAuth(权限检测,比如是否是需要登录的一个页面)、outputPage等这些方法,全是空方话,但是由一个run方法串起来。如下:

    public function run()
    
          {
    
              
    
               $this->getPara();
    
     
    
               $this->checkPara();
    
              
    
               $this->checkAuth();
    
     
    
               $this->main();
    
              
    
               $this->outputPage();
    
     
    
               $this->exitApp();
    
          }
    
     
    

      

    应用程序基类DCore_BaseApp.php的子类又分为三个,一个负责命令行程序的处理DCore_ConsoleApp.php,另外一个负责像移动应用、开放平台Api之类的数据处理DCore_ApiApp.php ,而第三个,则是DCore_WebApp.php, 我们所在浏览器上所访问的应用,由这个应用程序类派生出来页面类。而DCore_AdminApp.php,是管理后台应用程序类的基类。因为后端一般有不一样的权限认证机制。这样也是为了把前后台的应用程序类区分得更加清楚。

    这样可以看到,整体结构非常清晰。

    好,那最后我们再来看一下,需要编写哪些类库。

    在我们的框架中,编写了这些。

    •1、常用工具函数库

    实现字符串的常用操作封装,比如中文取字串,繁简转换、编码转换

    •2、模板引擎

    可以简化为包含PHP,在我们自己开发的这个框架中,支持了模板编译,其实模板编译很简单,就是将一些特定的语法,换成PHP代码,然后还是包含PHP

    •3、路由控制,静态化

    用户可以将路径改成搜索引擎更友好的路径,程序也能解析正确。

    •4、后端数据请求控制

    用于对后端一些公用操作的封装,比如数据库,比如Memcached,这样的封装带来的好处是,如果一旦发生升级或者替换的时候,修改的代码相对最少。比如你不用到处去改mysql_query,只需要修改当前这个库文件即可以了。

    八、总结

    好的,今天的课程就到这里。总结一下,我们讲了如下几点:

    1、5月课程尤其是5月份框架课程的总结。总结了框架与架构的区别。

    2、站在PHP框架之外,看框架,看框架的共同特征与功用。

    3、以PHP框架为例,讲框架所不能解决或者带来的问题。

    4、由于框架所带来的问题,以性能、可扩展问题,相对严重,所以分析PHP性能 的改造方向,总结了六大点。

    5、分别演示了这六大点的改进实践。包括Yaf、Phalcon框架介绍,zephir的使用,以及HHVM。

    6、汇总六大点的改进,并做了相关的性能评测。能看到,使用不同的技术差别巨大,所以我们要在稳定可靠的情况下,尽可能采用最好的技术。

    7、最后讲解了开发一个自有框架,一般都是一个什么样的思路。

  • 相关阅读:
    grunt in webstorm
    10+ Best Responsive HTML5 AngularJS Templates
    响应式布局
    responsive grid
    responsive layout
    js event bubble and capturing
    Understanding Service Types
    To add private variable to this Javascript literal object
    Centering HTML elements larger than their parents
    java5 新特性
  • 原文地址:https://www.cnblogs.com/hunhunrensheng/p/3782528.html
Copyright © 2020-2023  润新知