各開源框架使用與設計總結


    

一、框架課程總結


    框架、設計模式和隊列是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 \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、缺點

–還不是很穩定

–模塊需要遷移

 

六、各項實踐,性能評測

下面進入性能評測,評測我們相對就比較快速一些。直接用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、最后講解了開發一個自有框架,一般都是一個什么樣的思路。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM