php數組的方便性,很容易令人過度使用,其中一種過度使用的場合,就是做緩存時不區分場合濫用數組,導致性能不高,主要是集中在對CPU性能的高占用消耗上[1],以下以phpcms v9舉例說明.
phpcms v9中,作為模塊設計的pc標簽[2]其實是不錯的,易于讓人理解而且功能強大,但偏偏在關乎效率的緩存上似乎沒有意識到一個問題,絕大部分的開發者使用pc標簽的緩存參數,其實質是希望將該pc標簽包圍的模塊進行緩存,故而從緩存實現來講,作為一個視圖層而言,應該緩存最終渲染的html才對;但phpcms卻只是緩存了數據數組,每次讀取緩存并還原為數組后,仍然要進行渲染運算,這樣的結果,導致了pc標簽的緩存效率,其實沒有設計者想象的那么高.
比如如下pc標簽:
- {pc:content action=”position” posid=”1″ thumb=”1″ order=”listorder DESC” num=”5″ cache=”500″}
- <div class=”content” id=”main-slide”>
- <div class=”changeDiv”>
- {loop $data $r}
- <a href=”{$r['url']}” title=”{str_cut($r['title'],30)}”><img src=”{thumb($r['thumb'],310,260)}” alt=”{$r['title']}” width=”310″ height=”260″ /></a>
- {/loop}
- </div>
- </div>
- {/pc}
其本意應該是為了緩存該pc標簽包圍的焦點圖片模塊,但是生成的最終代碼發現,緩存的是中間從數據庫讀取出來的數組,仍需要每次渲染:
- <?php if(defined(‘IN_ADMIN’) && !defined(‘HTML’)) {echo “<div class=/”admin_piao/” pc_action=/”content/” data=/”op=content&tag_md5=2e957216affd4b95207c8d8eabcfb7b8&action=position&posid=1&thumb=1&order=listorder+DESC&num=5&cache=500&htmlblockcache=1/”><a href=/”javascript:void(0)/” class=/”admin_piao_edit/”>編輯</a>”;}$tag_cache_name = md5(implode(‘&’,array(‘posid’=>’1′,’thumb’=>’1′,’order’=>’listorder DESC’,'htmlblockcache’=>’1′,)).’2e957216affd4b95207c8d8eabcfb7b8′);if(!$data = tpl_cache($tag_cache_name,500)){$content_tag = pc_base::load_app_class(“content_tag”, “content”);if (method_exists($content_tag, ‘position’)) {$data = $content_tag->position(array(‘posid’=>’1′,’thumb’=>’1′,’order’=>’listorder DESC’,'htmlblockcache’=>’1′,’limit’=>’5′,));}if(!emptyempty($data)){setcache($tag_cache_name, $data, ‘tpl_data’);}}?>
- <div class=”content” id=”main-slide”>
- <div class=”changeDiv”>
- <?php $n=1;if(is_array($data)) foreach($data AS $r) { ?>
- <a href=”<?php echo $r['url'];?>” title=”<?php echo str_cut($r['title'],30);?>”><img src=”<?php echo thumb($r['thumb'],310,260);?>” alt=”<?php echo $r['title'];?>” width=”310″ height=”260″ /></a>
- <?php $n++;}unset($n); ?> //Vevb.com
- </div>
- </div>
- <?php if(defined(‘IN_ADMIN’) && !defined(‘HTML’)) {echo ‘</div>’;}?>
解決這種效率問題,最直接的方法是增加參數,允許改為存儲整塊最終渲染的HTML模塊,為此,改造了phpcms,允許增加一個htmlblockcache=”1″參數,前提是cache參數必須大于0,以解決此問題:
- {pc:content action=”position” posid=”1″ thumb=”1″ order=”listorder DESC” num=”5″ cache=”500″ htmlblockcache=”1″}
- {/pc}
受條件所限,ab測試只能在本機實驗。測試環境為:Win 2003 + IIS 6 + php 5.2,沒有安裝任何opcode緩存擴展。測試方法是:后臺更新(刪除)所有緩存后,在瀏覽器刷新首頁一次,以便重新生成所需緩存;首次兩輪-n 10 -c 10預熱,接著兩輪-n 600 -c 15正式測試,取第二次作對比。
測試結果發現,改造后的響應速度有提高不小,但是由于更新緩存時需要進行ob緩沖,其響應會偶爾偏高.
改造前(沒有htmlblockcache)的首頁測試結果:
- Document Path: /phpcmsv9/index.php
- Document Length: 41900 bytes
- Concurrency Level: 15
- Time taken for tests: 33.891 seconds
- Complete requests: 600
- Failed requests: 0
- Write errors: 0
- Total transferred: 25286400 bytes
- HTML transferred: 25140000 bytes
- Requests per second: 17.70 [#/sec] (mean)
- Time per request: 847.266 [ms] (mean)
- Time per request: 56.484 [ms] (mean, across all concurrent requests)
- Transfer rate: 728.63 [Kbytes/sec] received
- Connection Times (ms)
- min mean[+/-sd] median max
- Connect: 0 0 1.9 0 16
- Processing: 156 843 361.4 906 1875
- Waiting: 141 839 360.8 906 1875
- Total: 156 843 361.5 906 1875
- Percentage of the requests served within a certain time (ms)
- 50% 906
- 66% 1031
- 75% 1109
- 80% 1156
- 90% 1281
- 95% 1344
- 98% 1453
- 99% 1516
- 100% 1875 (longest request)
- 改造后(有htmlblockcache)的首頁測試結果:
- Document Path: /phpcmsv9/index.php
- Document Length: 41328 bytes
- Concurrency Level: 15
- Time taken for tests: 23.156 seconds
- Complete requests: 600
- Failed requests: 0
- Write errors: 0
- Total transferred: 24943200 bytes
- HTML transferred: 24796800 bytes
- Requests per second: 25.91 [#/sec] (mean)
- Time per request: 578.906 [ms] (mean)
- Time per request: 38.594 [ms] (mean, across all concurrent requests)
- Transfer rate: 1051.92 [Kbytes/sec] received
- Connection Times (ms)
- min mean[+/-sd] median max
- Connect: 0 1 5.9 0 109
- Processing: 94 570 177.5 547 2297
- Waiting: 94 563 177.7 547 2297
- Total: 94 571 177.3 547 2297
- Percentage of the requests served within a certain time (ms)
- 50% 547
- 66% 594
- 75% 625
- 80% 641
- 90% 703
- 95% 813
- 98% 1016
- 99% 1266
- 100% 2297 (longest request)
而實際服務器也支持這種測試結果——由于響應速度的提高,phpcgi的線程數也少了,CPU占用的疊加程度有所減少,負荷有所減輕.
新聞熱點
疑難解答