歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> 讓網站飛起來,PHP 程序加速探索

讓網站飛起來,PHP 程序加速探索

日期:2017/2/27 9:26:42   编辑:更多Linux
  (一)簡介  本文嘗試對PHP程序加速的各個方面進行探索,包括必要性以及從不同角度采取的具體措施。希望有助於讀者了解PHP程序加速,並應用於實際。    (二)是否需要加速?  這個問題聽起來有點愚蠢。在這個時代,很少有人會懷疑時間是最寶貴的財富,尤其是在商業市場上。程序執行越快,用戶就節約越多的時間,這樣你的程序就可以用更少的時間和服務器資源為用戶服務,從而產生更多效益。  我想對於大部份人(包括我自己)來說,很多WEB項目都是在很緊張的時間裡完成的,通常沒有經過缜密的思考和嚴格的測試。當開始一個新的WEB項目。很多人都在構建那種“快而亂”的應用,缺乏必要的時間來調整和改良代碼,這時優化和加速就是我們必須采取的措施。  然而需要特別指出的是,並不是所有程序都需要加速。  優化已完成的代碼是很浪費時間的,最好的方法是在寫代碼的時候就注意到效率,然後完成項目後只優化確實需要優化的那部份。一般一個程序只會有少數幾個影響速度的瓶頸,將它們找出來並解決掉,程序就可以很好地運行。另外,當遇到執行效率低下的情況,首先要用大局的眼光來找出影響效率的主要因素,而不要拘泥於細節—例如數據量過大,服務器帶寬不夠,或硬件配置過低,在這樣的情況下,優化代碼於事無補。  另外,在沒有發現程序有明顯的執行緩慢的跡象時,就不要太吹毛求疵,為了改進一些非常細節的代碼而浪費時間。用這些時間,你可以完成另一個項目或為原來的項目完成一個擴展功能。當然你可以笑話我不夠負責,沒有把工作做得盡善盡好,我也可以說你是完美主義者:-)  綜上,在你決定為你的PHP程序提速之前,問問自己是否有必要。    (三)如何加速?  要回答“如何加速”這個問題前,需要先回答以下兩個小問題:  你的程序慢在哪一部份?  PHP可以從哪幾個方面考慮加速?  第一個小問題顯然我無法給你答案,但我建議你用“測試腳本執行速度”的方法來解決。只有找出限制速度的瓶頸,才能考慮如何去解決。  第二個小問題我大概的答案是:代碼優化,壓縮輸出,內容緩存輸出,函數緩存輸出,加速/緩存工具軟件。如果你知道更多請告訴我:-)  下面我們來詳細地研究一下這幾個方面的相關技術。當然實際上每個方面都有無數的細節可以討論,下面的內容難免會有片面的地方,歡迎補充。     測試  ◆ 服務器負載測試    服務器負載太大而影響程序效率也是很常見的,我們需要對此進行測試。這裡我以目前最常用的Apache服務器為例。  Apache服務器自帶有一個叫AB(ApacheBench)的工具,在bin目錄下。使用這個輕巧的工具我們可以對服務器進行負載測試,看看在重負荷之下服務器的表現如何。ApacheBench 可以針對某個特定的 URL 仿真出連續的聯機請求,同時還可以仿真出同時間點數個相同的聯機請求,因此利用 ApacheBench 可幫助我們在網站開發期間仿真實際上線可能的情況,利用仿真出來的數據作為調整服務器設定或程序的依據。  在命令行下輸出:    ./ab -n number_of_total_requests -c number_of_simultaneous_requests http://your_web_server/your_php_app.php    例如:    ./ab -n 1000 -c 50 http://www.domain.com/myapp.php    AB將同時向http://www.domain.com/myapp.php發出50個並發請求,共發出1000次。  測試結果將可能是這樣的:    Server Software: Apache/2.0.16  Server Hostname: localhost  Server Port: 80  Document Path: /myapp.php  Document Length: 1311 bytes  Concurrency Level: 50  Time taken for tests: 8.794 seconds  Complete requests: 1000  Failed requests: 0  Total transferred: 1754000 bytes  Html transferred: 1311000 bytes  Requests per second: 113.71  Transfer rate: 199.45 kb/s received  Connection Times (ms)  min avg max  Connect: 0 0 5  Processing: 111 427 550  Total: 111 427 555    myapp.php每秒鐘可以處理的請求數為113.71個。將請求數增加,看看服務器能否處理更大的壓力。你也需要調節Apache的MaxClients, ThreadsPerChild, MaxThreadsPerChild 等參數,基於你的 httpd.conf 中的 MPM 模塊選擇。  如果你想得到更詳細的信息,請到www.apache.org上查閱一些更深入的文檔,包括模塊和第三方的提高效率的工具。修改httpd.conf後,要重啟Apache服務器,然後再用AB測試。你會看到每秒請求數增加或減少。  記下每次的參數,最後選擇最佳效率的那種配置。  要指出的是,除了AB,還有許多優秀的服務器性能測試軟件。另外,如果你的服務器不是 Apache,請自行尋找測試方法。    ◆ 腳本執行速度測試    前面有提到,只有找到影響速度的代碼,我們才有可能進行優化。PEAR的benchmark包中的Benchmark_Timer類和Benchmark_Iterate類,可以用來很方便地測試腳本執行的速度。(關於PEAR的安裝與配置請自行查看相關資料)  首先用Benchmark_Iterate類來測試程序中某個函數或類的某個方法的執行時間。    benchmark1.php        建立benchmark Iterate對象$benchmark,這個對象用來執行myFunction函數10次。  $argument變量每次都傳遞給myFunction. 多次運行的分析結果存入$result,然後用benchmark對象的get()方法來獲取。這個結果用print_r()輸出到屏幕。通常會輸出這樣的結果:  Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello  Array(  [1] => 0.000427  [2] => 0.000079  [3] => 0.000072  [4] => 0.000071  [5] => 0.000076  [6] => 0.000070  [7] => 0.000073  [8] => 0.000070  [9] => 0.000074  [10] => 0.000072  [mean] => 0.000108  [iterations] => 10)  myFunction的每次執行,benchmark對象都會跟蹤執行時間。並且會計算平均的執行時間([mean]那一行)。通過多次運行目標函數,你可以得到該函數的平均運行時間。  在實際測試中,函數的次數應當至少1000次左右,這樣可以得到較客觀的結果。    現在我們看看另一個測試腳本運行時間的方法--使用Benchmark_Timer類來測試一段代碼執行所消耗的時間及這一段代碼中每次調用與下一次調用間的時間。    benchmark2.php        首先,建立一個benchmark timer對象$timer。然後調用start()方法,表示開始計時。 SetMaker()方法用來標記要測試的代碼段。MyFunction()函數在循環中被調用,表示一段要執行的代碼(當然實際中不會這麼簡單)。然後再用$timer對象的setMarker()方法標記程序執行終點。分析信息用getProfiling()來獲取。在兩個標記間程序執行消耗的時間用timeElapsed()方法計算出來(就像例子中的循環)。最後,用print_r()輸出信息到屏幕:  Time elapsed: 0.000594    通過這種方法,你可以在代碼中設置大量時間段標記,獲取每段代碼執行時消耗的時間,很容易可以看出到底是哪一部份的代碼影響了整個程序的運行效率。然後開始著手對這部份代碼進行改進。  用以上兩種方法,你可以找出代碼中最影響速度的部份代碼。另外還可以用來對優化後的代碼進行測試,看看到底執行速度提高了多少。通過測試->優化->測試->優化 …這樣不斷循環,你可以最終確定提供最佳效率的代碼。     加速    ◆ 代碼優化  掌握了PEAR::BenchMark,現在你已經知道如何測試你的代碼,知道如何判斷你的代碼是快是慢,是哪一部份比較慢。那麼接下來我要說的就是如何消滅或優化那部份慢的代碼。  這一點上我個人最主要的經驗只有兩點,一是消除錯誤的或低效的循環;二是優化數據庫查詢語句。其實還存在一些其它的優化細節,比如“str_replace比ereg_replace快”、“echo比print快”等等。這些我暫時都放在一邊,稍後我會提到用緩存來對付過於頻繁的IO。  下面我們將三個功能相同,但程序寫法不同的函數的效率(消耗的時間)進行對比。    badloops.php    



Copyright © Linux教程網 All Rights Reserved