亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

使用APC加速PHP

2019-11-08 01:15:12
字體:
來源:轉載
供稿:網友

原文地址:http://devzone.zend.com/1812/using-apc-with-php/

注:打紅色的地方是拿不準的地方,讀者有懂的可以隨便賜教

Cache Cow

緩存牛(原文Cache Cow,醉了,第一個詞就不知道幾個意思,只能直譯了)

If you’ve been around PHP for a while, you’ve PRobably heard about APC, the Alternative PHP Cache. APC is an opcode cache that can significantly speed up your PHP applications, by caching both PHP code and user variables. Adding APC to an application usually results in improved application response times, reduced server load and happier users.

朋友,想來你已走進PHP的江湖有些時日,那么你應該聽說過APC(the Alternative PHP Cache)——可選PHP緩存。APC是一個通過緩存PHP 源碼和用戶變量來高效顯著加速你的PHP程序的opcode緩存。在應用中使用APC,通常伴隨著提升程序響應時間、減輕服務器負載和愉悅用戶的功效。

In this article, I’ll introduce you to APC, guiding you through the process of installing and configuring it and showing you a few examples of how it works. I’ll also walk you through the APC administrator interface, which lets you view APC performance in real time, and show you how you can use it with the Zend Framework. So come on in, and let’s get started!

本文中,我將向你介紹APC,帶領你安裝和配置APC,并且一起品嘗幾個例子來看看她是如何風騷的。同時將共你漫步在APC管理界面中,讓你實時欣賞APC的性能,最后再向你秀一下如何使用APC與Zend Framwork一起工作。前話點到即止,來吧!英雄!一起上吧?。?!

Getting Started

上,用力!

First up, a quick description of what APC is and how it works.

第一炮,先飛快地掃射一下APC是啥,咋干活。

As you probably already know, PHP is an interpreted language (unlike, say,java or C++). Whenever a client requests a PHP page, the server will read in the source code of the page, compile it into bytecode and then execute it. In the normal scenario, this process is performed on every request…although PHP is so speedy that you probably won’t even notice it!

當然了,你也許早已知曉,PHP是一種解釋性語言(異于  Java 或者 C++)。不管客官們幾時請求一個PHP頁面,服務務器都會把該頁面的源碼取出編譯字節碼而后執行。正常情況,都是要走這個流程的——盡管PHP已經快到肉眼無法觀測!

If you’re running an application or Web site that has many hundreds or thousands of requests coming in per minute, though, you’re going to want to speed things up as much as possible. And that’s where APC comes in. In the Words of its Web site, APC is “a free, open, and robust framework for caching and optimizing PHP intermediate code.” Very simply, APC caches the compiled output of each PHP script run and reuses it for subsequent requests. This reduces the time and processing cycles needed to fully satisfy each request, leading to better performance and lower response times.

如果你的應用或者網站每分鐘都有成千上萬的流量的話,相信你做夢都想著讓一切快到無極。很好,寶貝!APC在向你招手。APC是這么自稱的“哥是一個免費、開放、魯棒的用來緩存和優化PHP中間代碼的框架”。前人栽樹,后人乘涼。APC把PHP腳本編譯后的輸出緩存起來以供后來的請求復用和執行。這減少了滿足每一個請求所需的時間和處理周期,從而帶來更高的性能和更少的響應時間。

Does it work? You bet (there are some benchmarks at the end of the article). And it’s easy to set up as well. To install it, use the pecl command, as shown below:

想知道他是怎么干活的?你覺得呢(文件后面會有一些基準測試程序)。另外APC的安裝和配置也很簡單,來看看使用 pecl 命令安裝實例:

shell> pecl install apc-3.1.4

The PECL installer will now download the source code, compile it and install it to the appropriate location on your system.

執行上述命令后,pecl 安裝器將會下載源碼,編譯并且安裝到你系統的相關目錄下。

Alternatively, manually download the source code archive (v3.1.4 at this time) and compile it into a loadable PHP module with phpize:

無獨有偶,手動下載源碼包(撰寫本文時版本為3.14),使用phpize編譯為PHP可加載模塊的方法如下:

shell> cd apc-3.1.4

shell# phpize

shell# ./configure

shell# make

shell# make install

This procedure should create a loadable PHP module named apc.so in your PHP extension directory. You should now enable the extension in the php.iniconfiguration file, restart your Web server, and check that the extension is enabled with a quick call to phpinfo():

上面幾個步驟將生成一個名為apc.so的可加載模塊保存于你的PHP擴展目錄下,現在,修改你的PHP配置文件php.ini,重啟web服務器,就可以使用phpinfo()秒秒鐘看出來擴展是否裝上,是否可用。

Digging Deeper

深入!深入!

The APC source code archive includes a script named apc.php. This script serves as the administrator interface for the cache, allowing you to look inside the cache at any time to view usage or inspect cached variables. It’s a good idea to get familiar with how this works before starting to write any code.

APC源碼包包含了一個名為”apc.php”的腳本,提供了緩存的管理界面,讓我們隨時查看使用情況和監測緩存里的變量。在寫代碼之前,先搞清楚他的工作原理絕逼是美妙的。

To begin, extract the script from the source code archive and copy it to your Web server document root. Then, open it in a text editor and set the administrator password (you’ll find it near the top of the script). Once you’ve got that done, try accessing the script through your Web browser. You should see something like this:

來吧,先把這個腳本從源碼包里解壓出來放到你的web目錄下,用文本編輯器打開設置一下密碼(在腳本的前面幾行)。完事了之后就可以通過瀏覽器來訪問這個腳本了,下面這個界面將登場了:

As you can see, the script provides a birds-eye view of the current cache status, displaying general cache information, usage and statistics on hits and misses. The information is presented for both the system cache (which handles opcodes) and the user cache (which handles user variables). You’ll also see some interesting data derived from these statistics, such as the number of cache requests per second, the hit rate and miss rate.

正如你所見,這個頁面提供一個對當前系統緩存狀態、常用緩存信息、緩存使用情況和緩存成功及失敗的統計的概覽。這些信息同時展示系統緩存(保存著opcodes)和用戶緩存(保存著用戶變量)。從其余的統計信息中,我們還可以找到一些有趣的數據。例如緩存每秒請求數量,命中和的丟失的概率。

This information is useful to understand how well your cache is working, and identify areas that are under-optimized. In particular, note the cache full count value,which indicates how often the cache has filled up; if this is a high number, it’s an indication of high cache churn and suggests that you should perhaps assign more memory to the cache.

從這些信息中可以了解到你的緩存工作的優良情況,還能看出哪些部分處于優化狀態。特別要注意緩存完整計數值,它表明了緩存多長時間被填充一次;如果這是一個很大的數值,表明有大量的緩存流失,建議你可能是分配更多內存給緩存用。

The “System Cache Entries” tab lists the PHP scripts that are currently being cached, together with their filename, size and number of hits. Note that APC will automatically cache script opcode.

“System Cache Entries” 標簽列舉了當前被緩存的PHP腳本,包括文件名,大小和緩存被請求次數。注意:APC會自動緩存腳本的opcode。

The “User Cache Entries” tab lists user variables that have been stored in the cache, together with their identifier, size, and creation and modification times. You can select any of these entries to look inside the cache entry and see what it contains. Note that user cache entries must be manually created by a PHP script – you’ll see how on the next page.

“User Cache Entries” 標簽頁列舉了緩存的用戶數據,包含了ID、大小、創建和修改時間。你可以選擇任何一項去查看整個緩存整體里有些什么內容。但是這些用戶數據緩存是必須通過PHP手動創建——下面我們就來討論這個問題。

Remember that you can clear the opcode cache or the user cache at any time with the “Clear cache” buttons at the top right corner of the page.

記得可以隨時通過右上的“Clear cache”按鈕清除opcode 緩存和用戶數據緩存。

A Galaxy Far, Far Away

一個很遠很遠的星系

Now that you have a better idea of how APC works, let’s write some code. Caching user variables in APC is mainly done through the apc_add() and apc_fetch() methods, which allow variable to added to, and retrieved from, the cache respectively. Here’s a simple example that illustrates:

現在你對APC的工作方式有了一個清晰的概念了,可以開始寫點代碼了。在APC中緩存用戶數據主要通過apc_add() 和 apc_fetch() 兩個方法,前者用于添加,后者用于提取。下面我們來舉一個簡單的示例:

[php] view plain copy print?在CODE上查看代碼片<?php  if ($quote = apc_fetch('starwars')) {    echo $quote;    echo " [cached]";  } else {     $quote = "Do, or do not. There is no try. -- Yoda, Star Wars";      echo $quote;     apc_add('starwars', $quote, 120);  }  ?>  

Now,%20the%20first%20time,%20you%20run%20this%20script,%20the%20page%20will%20be%20generated%20from%20scratch%20and%20you’ll%20see%20something%20like%20this:

現在,運行這個腳本,這個頁面將從什么都沒有開始生成,你將看到如下畫面:

Next, try refreshing the page. This time, the output will be retrieved from the cache:

現在試著刷新頁面,這一次,輸出的變量將從緩存中取出來:

The business logic to use a cache is fairly simple. The first step is to check if the required data already exists in the cache. If it doesn’t, it should be generated from the original data source, and a copy saved to the cache for future use. If it does, you can use it right away – write it to a file, pipe it to an external program or output it to the client.

使用緩存的業務邏輯相當簡單。第一步就是檢查一下需要的數據是否已經存儲在緩存中,如果沒有,從原生數據中生成,并且保存一份到緩存中以備后用;如果有,那就可以直接用上了——寫文件,從管道輸出給外部程序或者直接輸出到客戶端。

In the previous example, checking whether the data already exists in the cache is accomplished with the apc_fetch() method, while writing a fresh snapshot to the cache is done with the apc_add() method. Notice that both methods require an ID; this ID uniquely identifies the object in the cache and serves as a key for saving and retrieving cache data. The apc_add() method additionally lets you specify a duration (in seconds) for which the cache is valid.

上一個例子中,檢查數據緩存與否是通過apc_fetch()這個方法來完成的,相應的寫一個新的快照到緩存中是通過apc_add()方法來完成的。需要注意的是,這兩個方法都需要一個 ID,用來唯一標識一個存儲在緩存中的對象,同時作為存取一個數據的鍵值。apc_add()這個方法還可以任你設置一個鍵的超時時間(以秒為單位)。

Take a look in the administrator interface, and you should see your cached data, together with statistics on cache hits and misses:

再瞅一眼管理界面,應該能看到緩存的數據了,還有緩存成功與失敗的統計:

A-rray of Sunshine

數組也有春天

In addition to caching strings, APC also allows you to cache arrays, objects, functions and references. Consider the following example, which caches an array of values:

天吶!你以為APC只能緩存字符串嗎?no!她還能緩存數組、對象、方法和引用 !??!來思考思考下面這個示例吧,它就緩存了一個數組的值:

[php] view plain copy print?在CODE上查看代碼片<?php  // if available, use cached array  // if not, create and cache array  if ($data = apc_fetch('heroes')) {    echo 'Cached data: ';  } else {     $data = array('Spiderman', 'Superman', 'Green Lantern', 'Human Torch');    apc_add('heroes', $data, 120);  }  echo $data[1];  // Superman  ?>  

You%20can%20also%20cache%20nested%20or%20multi-dimensional%20arrays,%20as%20shown%20below:

你還可以緩存多維數組哦,看哥給你秀下:

[php]%20view%20plain%20copy%20print?<?php  // if available, use cached data  // 如果緩存里有數據,就用緩存里的數據  // if not, create and cache nested array  // 如果沒有,創建一個多維數組,并且緩存起來  if ($data = apc_fetch('config')) {    echo 'Cached data: ';  } else {    $data = array(      'site1' => array(        'smtp' => array(          'host' => '192.168.0.1',          'user' => 'user1',          'pass' => 'guessme'        )      ),      'site2' => array(        'smtp' => array(          'host' => '192.168.10.10',          'user' => 'user2',          'pass' => 's3cr3t'        )      ),        );    apc_add('config', $data, 120);  }    // display data  echo $data['site2']['smtp']['pass']; // s3cr3t  ?>  An%20Object%20Lesson

下一課:緩存對象

In%20addition%20to%20caching%20arrays,%20APC%20also%20allows%20you%20to%20store%20objects%20in%20the%20cache.%20To%20illustrate,%20consider%20the%20next%20example,%20which%20initializes%20a%20simple%20User%20object,%20stores%20it%20in%20the%20cache,%20and%20then%20retrieves%20it%20back%20from%20the%20cache:

除了緩存數組,APC還能緩存對象。為了舉例說明,思考一下下面這個示例:初始化一個User對象,你保存到緩存中,再從緩存中取出使用。

[php]%20view%20plain%20copy%20print?<?php  class User {        private $name;    private $location;        function setName($value) {      $this->name = $value;    }        function setLocation($value) {      $this->location = $value;    }        function getName() {      return $this->name;    }        function getLocation() {      return $this->location;    }  }      if (apc_exists('user')) {    $obj = apc_fetch('user');    echo "Cached data: ";    } else {    $obj = new User;    $obj->setName('John');    $obj->setLocation('London');    apc_add('user', $obj, 120);  }    echo 'My name is ' . $obj->getName() . ' and I live in ' . $obj->getLocation();  ?>  Here’s%20what%20the%20output%20looks%20like:

能看來這樣的輸出:

第一次加載頁面:

第二次加載頁面:

Another approach to arrive at the same result is to serialize the object into a string, and then store the string in the cache instead of the object. Here’s what that would look like:

另一個異曲同工的方法是把對象序列化為一個字符串之后保存到緩存中,而不是直接緩存對象,示例如下:

[php] view plain copy print?在CODE上查看代碼片<?php  class User {        private $name;    private $location;        function setName($value) {      $this->name = $value;    }        function setLocation($value) {      $this->location = $value;    }        function getName() {      return $this->name;    }        function getLocation() {      return $this->location;    }  }      if ($str = apc_fetch('user')) {    $obj = unserialize($str);    echo "Cached data: ";    } else {     $obj = new User;    $obj->setName('John');    $obj->setLocation('London');    $str = serialize($obj);    apc_add('user', $str, 120);  }  echo 'My name is ' . $obj->getName() . ' and I live in ' . $obj->getLocation();  ?>  Getting%20Closure

緩存閉包

You%20can%20also%20use%20APC%20to%20cache%20references%20and%20(with%20a%20little%20tweaking)%20anonymous%20functions.%20Let’s%20take%20a%20look:

你也可以使用APC來緩存引用和匿名函數,看下面:

[php]%20view%20plain%20copy%20print?<?php  class Calendar {    public $year = 2001;    public function &getYear() {      return $this->year;    }  }    $obj = new Calendar;  $a = &$obj->getYear();  // 2001  $obj->year = 2010;      // 2010  apc_add('ref', $a, 60);  $ref = apc_fetch('ref');  $ref++;                   echo $ref;              // 2011  ?>  Anonymous%20functions%20or closures,%20new%20in%20PHP%205.3,%20offer%20an%20easy%20way%20to%20define%20functions%20“on%20the%20fly”.%20By%20default,%20however,%20closures%20cannot%20be%20cached%20with%20APC,%20as%20the%20Closure%20class%20does%20not%20implement%20serialization.%20Here’s%20a%20simple%20example%20that%20illustrates%20the%20problem:

匿名函數,或稱為閉包,是%20PHP5.3%20的新特性,提供一種簡單的懸空的方式來定義函數。默認情況下,APC無論如何是不能緩存閉包的,因為閉包沒有實現序列化。這兒有一個簡單的示例說明該問題:

[php]%20view%20plain%20copy%20print?<?php  // check if closure exists in cache  // if yes, retrieve and use  // if not, define and add to cache  if (!apc_exists('area')) {    // simple closure    // calculates area from length and width    $area = function($length, $width) {        return $length * $width;    };    apc_store('area', $area);    echo 'Added closure to cache.';    } else {    $func = apc_fetch('area');    echo 'Retrieved closure from cache. ';    echo 'The area of a 6x5 polygon is: ' . $func(6,5);    }  ?>  When%20you%20try%20accessing%20this%20script,%20you’ll%20see%20an%20error%20about%20serialization,%20as%20shown%20below:

執行這個腳本,你會看到下面這個關于序列化的錯誤:

FastCGI%20sent%20in%20stderr:%20"PHP%20message:%20PHP%20Fatal%20error: %20Uncaught%20exception%20'Exception'%20with%20message%20'Serialization%20of%20'Closure'%20is%20not%20allowed'

What’s%20the%20solution?%20Well,%20Jeremy%20Lindblom%20has%20extended%20the%20Closure%20class%20and%20created a%20custom%20SuperClosure%20class that%20supports%20both%20serialization%20and%20reflection.%20If%20you%20implement%20your%20closure%20using%20this%20class,%20you%20will%20be%20able%20to%20cache%20it.%20Here’s%20a%20revision%20of%20the%20previous%20script%20that%20demonstrates:

有什么解決辦法呢?有的,Jeremy%20Lindblom%20擴展了增長包類并且創建了 a%20custom%20SuperClosure%20class 來同時支持序列化和反射。如果你是使用這個類實現的閉包,那么就可以緩存它了。下面是對上文腳本的改進:

[php]%20view%20plain%20copy%20print?<?php  // include SuperClosure class  include 'SuperClosure.class.php';    // check if closure exists in cache  // if yes, retrieve and use  // if not, define and add to cache  if (!apc_exists('area')) {    // simple closure    // calculates area given length and width    $area = new SuperClosure(      function($length, $width) {        return $length * $width;      }    );    apc_store('area', $area);    echo 'Added closure to cache.';    } else {    $func = apc_fetch('area');    echo 'Retrieved closure from cache. ';    echo 'The area of a 6x5 polygon is: ' . $func(6,5);    }  ?>  Here’s%20what%20the%20output%20looks%20like:

顯示如下:

第一次瀏覽:

第二次瀏覽:

Note that these examples use apc_store() instead of apc_add(). In most cases, you can use these two functions interchangeably. The primary difference lies in how they behave when you attempt to store a value using an identifier that already exists in the cache: apc_add() will return false, while apc_store()will overwrite the previous value with the new value.

注意,這些實例使用apc_store() 代替 apc_add()。大多數情況下,你可以互換著這兩個函數使用。主要的不同之處在于,當你使用一個緩存中已有的ID來存儲數據時:apc_add()會返回 false,而 apc_store() 會使用新的值覆蓋之前的值。

You can download the SuperClosure class definition from Jeremy Lindblom’s Github account.

你可以從 Jeremy Lindblom’s Github 賬戶上下載SuperClosure 這個類的定義。(注:剛瀏覽了下這個頁面不存在,不過還可以從http://www.htmlist.com/development/extending-php-5-3-closures-with-serialization-and-reflection/上面直接拷貝一份使用)。

Utility Belt

實用技能

The APC extension also comes with a few other methods of note. For example, there’s the apc_inc() and apc_dec() methods, which can be used to increment or decrement cached values respectively:

APC擴展還有一些其余的方法和備注。例如:apc_inc()  和 apc_dec() 方法分別作用緩存值的自增和自減。

[php] view plain copy print?在CODE上查看代碼片<?php  // store a value  apc_store('a', 20);    // increment and decrement stored value  apc_inc('a');         // 21  apc_inc('a');         // 22  apc_inc('a');         // 23  apc_dec('a');         // 22    // retrieve final value  echo apc_fetch('a');  // 22  ?>  The apc_bin_dump() method%20dumps%20the%20current%20contents%20of%20the%20cache%20in%20binary%20form,%20while%20the apc_bin_load() method%20loads%20a%20binary%20dump%20into%20the%20cache.%20Consider%20the%20following%20example,%20which%20illustrates:

apc_bin_dump()方法從緩存中把當前內容導出為二進制形式,而apc_bin_load()%20方法則反之。仔細考慮以述實例:

[php]%20view%20plain%20copy%20print?<?php  // clear cache  apc_clear_cache();  apc_clear_cache('user');    // store some values  apc_store('a', 20001);  apc_store('b', 7494);    // dump cache in binary form  $dump = apc_bin_dump();    // clear cache  apc_clear_cache();  apc_clear_cache('user');    // try accessing a stored value  if (apc_fetch('a')) {    echo apc_fetch('a');  } else {    echo 'Nothing in cache';   }  // reload cache from binary dump  apc_bin_load($dump);    // try accessing a stored value  if (apc_fetch('a')) {    echo apc_fetch('a');     // 20001  } else {    echo 'Nothing in cache';   }  ?>  The apc_clear_cache() method%20can%20be%20used%20to%20clear%20the%20opcode%20cache%20or%20the%20user%20cache:

apc_clear_cache()%20方法可以用來清除opcode%20緩存或者用戶緩存:

[php]%20view%20plain%20copy%20print?<?php  // clear opcode cache  apc_clear_cache();    // clear user cache  apc_clear_cache('user');  ?>  

The apc_cache_info() method%20presents%20information%20on%20current%20cache%20status%20and%20memory%20allocation:

apc_cache_info()%20方法能夠提供當前緩存狀態和內存分配信息

[php]%20view%20plain%20copy%20print?<?php  print_r(apc_cache_info());  ?>  Here’s%20what%20the%20output%20looks%20like:

執行上述腳本能看到:

Tweet Tweet

推倒!推倒!

With all this background information at hand, let’s try APC with a real-world example. This next script uses APC to cache the result of a Twitter search:

Get 到這些新技能之后,讓我們來現實世界里走你一個。接下來這個腳本用APC來緩存推特的搜索結果 :

[php] view plain copy print?在CODE上查看代碼片<html>    <head>      <style type="text/CSS">        div.outer {        border-bottom: dashed orange 1px;        padding: 4px;        clear: both;        height: 50px;        }                div.img {          float:left;          padding-right: 2px;        }        span.attrib {          font-style: italic;        }      </style>      </head>      <body>      <h2>Twitter Search</h2>      <form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">      Search term: <input type="text" name="q" />      <input type="submit" name="submit" />      </form>     <?php      // if form submitted      if (isset($_POST['submit'])):        // sanitize query terms        $q = strip_tags($_POST['q']);                // generate cache id from query term        $id = md5($q);                // check if this search already exists in cache        // use if yes, generate fresh results and add to cache if no        if (apc_exists($id)) {          $records = apc_fetch($id);                } else {          // search Twitter for query term          $result = simplexml_load_file("http://search.twitter.com/search.atom?q=$q&lang=en");                  // process Atom feed of search results          $records = array();          foreach ($result->entry as $entry) {            $item['image'] = (string)$entry->link[1]['href'];             $item['owner'] = (string)$entry->author->name;            $item['uri'] = (string)$entry->author->uri;            $item['tweet'] = (string)$entry->content;            $item['time'] = date('d M Y, h:i', strtotime($entry->published));             $records[] = $item;          }                    // cache for 5 minutes          apc_store($id, $records, 300);        }                    // display search results  ?>      <h2>Twitter Search Results for '<?php echo $q; ?>'</h2>        <?php foreach ($records as $r): ?>        <div class="outer">          <div class="img"><img width=48" height="48" src="<?php echo $r['image']; ?>" /></div>          <div><?php echo $r['tweet']; ?><br/>           <span class="attrib">By <a href="<?php echo $r['uri']; ?>"><?php echo $r['owner']; ?></a>           on <?php echo $r['time']; ?></span></div>        </div>         <?php endforeach; ?>      <?php endif; ?>    </body>  </html>     Despite%20its%20length,%20this%20is%20actually%20a%20very%20simple%20script.%20It%20begins%20by%20creating%20a%20search%20form%20for%20the%20user%20to%20enter%20search%20terms%20into.%20Once%20this%20form%20is%20submitted,%20it%20connects%20to the%20Twitter%20Search%20API,%20retrieves%20an%20Atom-formatted%20list%20of%20search%20results%20matching%20the%20search%20term,%20process%20the%20Atom%20feed%20and%20render%20the%20final%20output%20as%20an%20HTML%20table.%20The%20results%20of%20the%20search%20are%20cached%20for%20five%20minutes,%20so%20that%20they%20can%20be%20used%20for%20subsequent%20searches%20containing%20the%20same%20search%20terms.%20Notice%20that%20each%20search%20query%20is%20assigned%20a%20unique%20identifier%20in%20the%20APC%20cache,%20by%20using%20its%20MD5%20signature%20as%20key.

盡管不算長(估計是這意思),但確實是一個簡單的腳本。開始處創建了一個表單給用戶輸入需要搜索的詞條。一旦表單提交之后,連接推特的搜索接口,檢索出Atom%20格式化過的匹配搜索條目的結果列表,處理%20Atom%20格式提取出最終數據輸出為html表格渲染到頁面上。這些結果將被緩存五分鐘,以備后續有相同搜索條止的請求使用。注意每一次搜索條件查詢都會分配到通過md5簽名成鍵作為唯一的APC緩存ID。

You%20will%20realize%20that%20there%20are%20two%20levels%20of%20caching%20in%20this%20script.%20First,%20APC’s%20opcode%20cache%20is%20automatically%20caching%20the%20compiled%20bytecode%20of%20the%20script,%20and%20using%20this%20cached%20bytecode%20for%20subsequent%20requests%20instead%20of%20recompiling%20it%20a%20new.%20Second,%20APC’s%20user%20cache%20is%20caching%20the%20results%20of%20each%20Twitter%20search,%20and%20reusing%20these%20results%20(instead%20of%20connecting%20to%20Twitter%20afresh)%20for%20subsequent%20searches%20containing%20the%20same%20query%20terms.%20As%20a%20result,%20subsequent%20searches%20for%20the%20same%20term%20will%20be%20served%20from%20the%20cache,%20leading%20to%20a%20noticeable%20reduction%20in%20load%20time%20(try%20it%20for%20yourself%20and%20see).

你會發現在這個腳本中做了兩層緩存。首先,APC的opcode緩存是自己緩存腳本的編譯過的字節碼的,并且在后續的請求中使用這些字節碼而不是重新編譯一份。其次,APC的用戶緩存是緩存推特的搜索結果,然而在后續有相同檢索條目的請求中使用這些結果(而不是重新連接推特)。這就能使得后續相同的搜索服務于緩存,為我們贏來更少的加載時間(請知行合一)。

Here’s%20an%20example%20of%20what%20the%20output%20looks%20like:

請看示例:(剛剛看了下推特的這個api已經停用了,就不管他了)

In The Frame

框架中使用

If you’re a fan of the Zend Framework, you’ll be happy to hear thatZend_Cache comes with built-in support for APC, allowing you to begin using it out of the box. To illustrate, consider the following Zend Framework controller, which revises the previous example into a Zend Framework controller:

如果你是Zend Framework 迷。那么你將會喜聞樂見Zend_Cache 已經內建支持APC,你可以開始使用它原裝的了。好好研究下面這個使用Zend Framework 控制層的實例,我們將用Zend Framwork 控制層來改進上一個例子的實現向你闡明APC 在Zend Framework 中的使用:

[php] view plain copy print?在CODE上查看代碼片<?php  class IndexController extends Zend_Controller_Action  {      public function indexAction()      {          // action body      }        public function searchAction()      {        // initialize cache        $cache = Zend_Cache::factory( 'Core',                                       'APC',                                       array('lifeTime' => 300, 'automatic_serialization' => true));          // create form and attach to view                                                  $form = new SearchForm();        $this->view->form = $form;                       // validate input              if ($this->getRequest()->isPost()) {          if ($form->isValid($this->getRequest()->getPost())) {            // get sanitized input            $values = $form->getValues();                                // calculate MD5 hash            $id = md5($values['q']);                        // look for records in cache            if (!$records = $cache->load($id) ){                                     // if not present in cache              // search Twitter for query term              $result = simplexml_load_file("http://search.twitter.com/search.atom?q=" . $values['q'] . "&lang=en");                            // process Atom feed of search results              $records = array();              foreach ($result->entry as $entry) {                $item['image'] = (string)$entry->link[1]['href'];                 $item['owner'] = (string)$entry->author->name;                $item['uri'] = (string)$entry->author->uri;                $item['tweet'] = (string)$entry->content;                $item['time'] = date('d M Y, h:i', strtotime($entry->published));                 $records[] = $item;              }                            // save to cache              $cache->save($records, $id);            }                        // assign results to view            $this->view->records = $records;            $this->view->q = $values['q'];          }                   }             }  }    // search form  class SearchForm extends Zend_Form  {    public function init()    {      // initialize form      $this->setMethod('post');                 // create text input for search term      $q = new Zend_Form_Element_Text('q');      $q->setLabel('Search term:')           ->setOptions(array('size' => '35'))           ->setRequired(true)           ->addValidator('NotEmpty', true)           ->addFilter('HTMLEntities')                       ->addFilter('StringTrim');                        // create submit button      $submit = new Zend_Form_Element_Submit('submit');      $submit->setLabel('Search');                        // attach elements to form      $this->addElement($q)           ->addElement($submit);    }  }?>  

Here,%20the searchAction() method%20first%20sets%20up%20the%20Zend_Cache%20instance,%20with%20the%20Core%20frontend%20and%20the%20APC%20backend.%20The%20form%20object,%20which%20extends%20Zend_Form,%20is%20then%20added%20to%20the%20view,%20together%20with%20all%20necessary%20validators%20and%20filters,%20and%20the%20view%20is%20rendered.

本例中,searchAction()%20方法首先生成一個以Core為前端和以APC為后端的Zend_Cache實例,繼承自Zend_Form的表單對象,添加到頁面中,還帶有驗證和過濾的功能,接著渲染頁面。

When%20the%20user%20submits%20the%20form,%20control%20transfers%20back%20to%20the%20action%20controller,%20which%20checks%20the%20input%20and%20retrieves%20the%20filtered%20values.%20It%20then%20checks%20the%20cache%20to%20see%20if%20a%20search%20result%20already%20exists%20for%20this%20search%20term,%20and%20uses%20it%20if%20available;%20if%20not,%20it%20connects%20to%20the%20Twitter%20Search%20API,%20retrieves%20a%20result%20set,%20and%20saves%20it%20to%20the%20cache%20for%20future%20use.%20The%20results%20are%20then%20rendered%20through%20the%20view%20script.%20On%20subsequent%20searches%20for%20the%20same%20term,%20the%20cached%20result%20set%20will%20be%20used,%20producing%20a%20much%20faster%20response.

用戶提交表單后,控制轉移到后面的控制層,用以驗證輸入和提取過濾后的內容。接下來檢查一下緩存中是否有相同搜索條目的存儲,如果有取出使用,如果沒有,連接推特的搜索API,取出結果集,并且保存一份到緩存中以備后用。然后通過腳本把結果渲染到頁面上。后來的搜索如果是相同的詞條,這些緩存里的結果集就可以用上了,這就大大提升了響應速度。

Here’s%20the%20code%20for%20the%20view%20script:

下面是頁面代碼:

[php]%20view%20plain%20copy%20print?<style type="text/css">    div.outer {    border-bottom: dashed orange 1px;    padding: 4px;    clear: both;    height: 50px;    }            div.img {      float:left;      padding-right: 2px;    }    span.attrib {      font-style: italic;    }  </style>  <h2>Twitter Search</h2  <?php echo $this->form; ?>    <?php if ($this->records): ?>    <h2>Twitter Search Results for '<?php echo $this->q; ?>'</h2>    <?php foreach ($this->records as $r): ?>    <div class="outer">      <div class="img"><img width=48" height="48" src="<?php echo $r['image']; ?>" /></div>      <div><?php echo $r['tweet']; ?><br/>       <span class="attrib">By <a href="<?php echo $r['uri']; ?>"><?php echo $r['owner']; ?></a>       on <?php echo $r['time']; ?></span></div>    </div>     <?php endforeach; ?>  <?php endif; ?>  And%20here’s%20a%20sample%20of%20the%20output:

渲染結果:(由于推特這么接口關了,此處省略一張圖)

The%20Need%20For%20Speed

速之所需

At%20this%20point,%20there’s%20only%20one%20question%20left%20to%20answer:%20does%20APC’s%20opcode%20caching%20really%20deliver%20the%20goods%20and%20produce%20a%20verifiable%20increase%20in%20performance?

到了這個點上,還有最后一個問題了:APC%20的opcode%20緩存是否真能不負眾望,為我們帶來可見的性能上的提升?

A%20good%20way%20to%20test%20this%20is%20by%20benchmarking%20a%20PHP%20script%20with%20and%20without%20APC,%20and%20evaluating%20the%20performance%20differential%20if%20any.%20ApacheBench%20(ab)%20is%20my%20tool%20of%20choice%20for%20this%20test,%20and%20my%20testbed%20will%20be%20the%20default%20welcome%20page%20of%20a%20new%20Zend%20Framework%20project.%20You%20can%20create%20this%20by%20installing%20the%20Zend%20Framework%20and%20then%20using%20the zf command-line%20tool to%20initialize%20a%20new,%20empty%20project,%20like%20this:

最好的辦法就是對同一個腳本使用和不使用APC做基準測試,評估所有性能的差異。我選擇ApacheBench(ab)作為測試工具,Zend%20Framework%20項目默認歡迎頁為測試腳本。你安裝好%20Zend%20Framework%20之后,你可以使用它的命令行工具zf來初始化一個新的空項目,例如:

shell>%20zf%20create%20project%20example

Now,%20turn%20off%20APC,%20by%20 %20the%20extension%20in%20your php.ini configuration%20file%20and%20restarting%20the%20Web%20server.%20Then,%20use ab to%20benchmark%20the%20application%20welcome%20page%20by%20sending%20it%201000%20requests%20with%20a%20concurrency%20level%20of%205,%20as%20follows:

現在,通過配置php.ini%20來禁用APC并且重啟web服務器。然后,使用ab做一個基準測試:向該歡迎頁做1000次請求,并發級別為5,如下:

[plain]%20view%20plain%20copy%20print?shell> ab -n 1000 -c 5 http://example.localhost/default/index/index  On%20my%20development%20system,%20this%20produces%20output%20like%20the%20following:

在我的開發系統上,這個命令產生的結果如下:

[plain]%20view%20plain%20copy%20print?This is ApacheBench, Version 2.3 <$Revision: 655654 $>  Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/  Licensed to The Apache Software Foundation, http://www.apache.org/    Benchmarking localhost (be patient)  Completed 100 requests  Completed 200 requests  Completed 300 requests  Completed 400 requests  Completed 500 requests  Completed 600 requests  Completed 700 requests  Completed 800 requests  Completed 900 requests  Completed 1000 requests  Finished 1000 requests      Server Software:        nginx/1.5.3  Server Hostname:        localhost  Server Port:            1234    Document Path:          /php/apc/exam12/public/index.php  Document Length:        1042 bytes    Concurrency Level:      5  Time taken for tests:   10.206 seconds  Complete requests:      1000  Failed requests:        0  Write errors:           0  Total transferred:      1189000 bytes  HTML transferred:       1042000 bytes  Requests per second:    97.98 [#/sec] (mean)  Time per request:       51.031 [ms] (mean)  Time per request:       10.206 [ms] (mean, across all concurrent requests)  Transfer rate:          113.77 [Kbytes/sec] received    Connection Times (ms)                min  mean[+/-sd] median   max  Connect:        0    1   1.3      0       9  Processing:    31   50   8.4     48      96  Waiting:       31   50   8.4     48      96  Total:         31   51   8.3     49      96    Percentage of the requests served within a certain time (ms)    50%     49    66%     52    75%     54    80%     55    90%     63    95%     69    98%     74    99%     79   100%     96 (longest request)  The%20main%20numbers%20to%20look%20at%20here%20are%20the%20requests%20per%20second%20and%20the%20average%20time%20per%20request.%20The%20lower%20the%20average%20time%20per%20request,%20the%20better%20the%20performance.%20Similarly,%20the%20greater%20the%20number%20of%20requests%20served,%20the%20better%20the%20performance.

主要關注的數據是requests%20per%20second(每秒處理次數)%20和%20the%20average%20time%20per%20request(每個請求平均用時)。平時請求時長越短,性能越好。同理,每秒處理次數越大,性能越好。

Next,%20re-enable%20APC,%20restart%20the%20Web%20server%20and%20try%20the%20test%20again.%20On%20my%20development%20system,%20this%20produces%20output%20like%20the%20following:

下面,打開APC,重啟WEB服務器,再試一次,我的開發機上效果是這樣子的:

[html]%20view%20plain%20copy%20print?派生到我的代碼片This is ApacheBench, Version 2.3 <$Revision: 655654 $>  Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/  Licensed to The Apache Software Foundation, http://www.apache.org/    Benchmarking localhost (be patient)  Completed 100 requests  Completed 200 requests  Completed 300 requests  Completed 400 requests  Completed 500 requests  Completed 600 requests  Completed 700 requests  Completed 800 requests  Completed 900 requests  Completed 1000 requests  Finished 1000 requests      Server Software:        nginx/1.5.3  Server Hostname:        localhost  Server Port:            1234    Document Path:          /php/apc/exam12/public/index.php  Document Length:        0 bytes    Concurrency Level:      5  Time taken for tests:   3.917 seconds  Complete requests:      1000  Failed requests:        996     (Connect: 0, Receive: 0, Length: 996, Exceptions: 0)  Write errors:           0  Non-2xx responses:      4  Total transferred:      1184908 bytes  HTML transferred:       1037832 bytes  Requests per second:    255.32 [#/sec] (mean)  Time per request:       19.583 [ms] (mean)  Time per request:       3.917 [ms] (mean, across all concurrent requests)  Transfer rate:          295.44 [Kbytes/sec] received    Connection Times (ms)                min  mean[+/-sd] median   max  Connect:        0    0   0.7      0       7  Processing:     4   19   5.2     18      42  Waiting:        4   19   5.2     18      42  Total:          5   20   5.2     18      43    Percentage of the requests served within a certain time (ms)    50%     18    66%     22    75%     23    80%     24    90%     26    95%     28    98%     33    99%     36     100%     43 (longest request)  

As you can see, enabling APC has resulted in an almost 185% increase in performance, with the server now being able to handle 71 requests per second (up from 25 earlier) and the average time per request coming down to 69 ms (from 194 ms earlier).

看見沒有!開啟APC的結果就是提升200%多的性能!看看吧,現在每秒請求次數和平時請求時長分別優化了多少?自!已??!算?。?!

The above test was run with APC’s default settings. However, APC comes with a number of configuration settings that you can tweak further to squeeze even better performance from it. Here are some of the important ones:

上述測試都是基于APC默認配置的。但是,APC是有著大把專屬的配置的,你可以慢慢調整來壓榨出更高的性能?,F在先來看看幾個比較重置的配置項:

‘apc.shm_size’ controls the size of the APC memory cache;‘apc.shm_size’ 控制APC緩存的容量;‘apc.stat’ controls whether APC checks each script to see if it has been modified and needs to be recompiled and recached;‘apc.stat’ 控制APC是否挨個腳本檢查變更以否和是否需要重新編譯重新緩存;‘apc.optimization’ determines the degree of optimization to apply;‘apc.optimization’ 決定應用的優化程度;‘apc.filters’ specifies which files should be cached;‘apc.filters’ 指定哪些文件需要緩存;‘apc.write_lock’ places an exclusive lock for caching compiled script bytecode;‘apc.write_lock’  置入腳本編譯的字節碼的獨占鎖;‘apc.lazy_functions’ and ‘apc.lazy_classes’ enables lazy loading for functions and classes.‘apc.lazy_functions’ 和 ‘apc.lazy_classes’ 開啟函數和類的延遲加載。

You can read more about these and other configuration directives here.

猛戳這里獲取更多配置信息。

That’s about all I have for the moment. I hope this tutorial has given you some insight into how APC works, and how you can use it to improve the performance of your PHP applications. Try it out the next time you have a performance optimization problem, and see what you think!

這些就是哥目前所知所識了。希望這個教程能讓你看清APC脫下褲子是怎么干活滴,你怎么樣可以使用它來提升你的PHP應用的性能。下次再有性能優化難題的時間,好好試試,你就能融會貫通,達到知行合一的境界。

Copyright Melonfire, 2010. All rights reserved.

版權歸哥所有。哥保留所有權利。2010年書。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩av在线免费观看| 国产精品入口日韩视频大尺度| 国产精品视频色| 高清在线视频日韩欧美| 日韩av三级在线观看| 欧美成人在线免费视频| 中文字幕日韩av电影| 色琪琪综合男人的天堂aⅴ视频| 亚洲美女在线视频| 欧美肥臀大乳一区二区免费视频| 国产精品v片在线观看不卡| 亚洲а∨天堂久久精品喷水| 国产精品老女人视频| 国产在线999| 日韩a**中文字幕| 97视频在线观看亚洲| 57pao成人国产永久免费| 国产精品久久综合av爱欲tv| 国产视频在线观看一区二区| 久久精品91久久久久久再现| 一本色道久久综合狠狠躁篇怎么玩| 国产精品久久中文| 国产精品网红福利| 日本免费久久高清视频| 国产欧美韩国高清| 久久久久久国产精品三级玉女聊斋| 国产福利精品视频| 国产精品www| 亚洲一区二区三区在线免费观看| 欧美中文字幕在线视频| 久久免费视频网站| 最新日韩中文字幕| 国产精品户外野外| 欧美日韩国产中字| 欧美怡红院视频一区二区三区| 欧美中文在线观看| 91精品久久久久久久久不口人| 日本免费久久高清视频| 亚洲精选一区二区| 夜夜嗨av色一区二区不卡| 精品视频偷偷看在线观看| 久久视频这里只有精品| 免费av在线一区| 欧美乱大交xxxxx| 国产脚交av在线一区二区| 国产成人鲁鲁免费视频a| 91免费看国产| 日韩三级成人av网| 日韩精品在线观看一区二区| 8090成年在线看片午夜| 欧美制服第一页| 亚州精品天堂中文字幕| 精品日本美女福利在线观看| 亚洲欧美日韩综合| 日韩电视剧在线观看免费网站| 国产欧美一区二区三区在线| 亚洲性视频网址| 91免费人成网站在线观看18| 欧美性高跟鞋xxxxhd| 国产精品免费视频久久久| 欧美猛少妇色xxxxx| 久久综合九色九九| 亚洲精品videossex少妇| 亚洲欧美中文字幕| 97国产一区二区精品久久呦| 精品久久久久久国产91| 亚洲激情视频在线| 欧美日韩国产在线看| 亚洲精品xxx| 国产成人av在线播放| 成人中文字幕+乱码+中文字幕| 久久亚洲精品中文字幕冲田杏梨| 精品国产老师黑色丝袜高跟鞋| 另类图片亚洲另类| 亚洲成人久久久久| 欧美亚洲国产视频| 91在线精品视频| 国产成人在线播放| 国产69精品久久久| 亚洲欧美一区二区三区四区| 91性高湖久久久久久久久_久久99| 狠狠干狠狠久久| 国产精品亚洲美女av网站| 视频一区视频二区国产精品| 欧美激情videoshd| 欧美日韩国产在线播放| 狠狠爱在线视频一区| 国产精品成人一区二区| 57pao成人国产永久免费| 亚洲国产精品va在线观看黑人| 日韩成人中文字幕| 国产91热爆ts人妖在线| 九九精品视频在线观看| 91精品啪aⅴ在线观看国产| 国产精品女人网站| 亚洲精品免费一区二区三区| 日韩在线视频网| 日韩暖暖在线视频| 欧美乱大交xxxxx另类电影| 精品久久中文字幕久久av| 亚洲美女又黄又爽在线观看| 亚洲人a成www在线影院| 亚洲人高潮女人毛茸茸| 亚洲天堂免费视频| 性欧美长视频免费观看不卡| 97精品视频在线| 久久这里只有精品视频首页| 国产精品va在线播放我和闺蜜| 日韩视频永久免费观看| 中文字幕av一区二区| 国产精品一区二区三区久久久| 美女999久久久精品视频| 国产免费一区二区三区在线能观看| 亚洲精品久久久久中文字幕欢迎你| 国产日韩在线一区| 亚洲视频在线播放| 九九热在线精品视频| 91深夜福利视频| 日韩中文字幕精品视频| 日韩有码在线播放| 成人免费视频a| 国产精品96久久久久久又黄又硬| 精品一区二区三区电影| 奇门遁甲1982国语版免费观看高清| 亚洲欧美制服中文字幕| 亚洲国产精品国自产拍av秋霞| 欧美日韩在线一区| 欧美与欧洲交xxxx免费观看| 国产综合福利在线| 国产成人综合精品在线| 在线成人中文字幕| 国产精品第一第二| 久久久这里只有精品视频| 麻豆乱码国产一区二区三区| 日本久久久久久久| 亚洲自拍小视频免费观看| 91九色视频在线| 亚洲视屏在线播放| 亚洲国产成人精品女人久久久| 日韩免费av在线| 日本在线观看天堂男亚洲| 97av在线视频免费播放| 国产成人精品电影| 欧美国产日产韩国视频| 国产精品国产自产拍高清av水多| 91精品久久久久久久久久久| 精品电影在线观看| 久久艳片www.17c.com| 永久免费毛片在线播放不卡| 亚洲国产精品系列| 国产v综合ⅴ日韩v欧美大片| 欧美精品在线观看91| 午夜美女久久久久爽久久| 日韩亚洲精品视频| 欧美性xxxx极品hd满灌| 亚洲激情电影中文字幕| 亚洲最大福利视频| 亚洲国产欧美一区| 国产精品一区二区三区成人| 亚洲精品乱码久久久久久按摩观| 日韩亚洲精品视频| 国产精品igao视频| 久久国产精品影片| 国产欧美日韩中文|