導航:首頁 > 編程語言 > 判斷php運行模式

判斷php運行模式

發布時間:2024-06-14 06:58:02

php的性能探討和測試


1.緣起
關於PHP,很多人的直觀感覺是PHP是一種靈活的腳本語言,庫類豐富,使用簡單,安全,非常適合WEB開發,但性能低下。PHP的性能是否真的就如同大家的感覺一樣的差呢?本文就是圍繞這么一個話題來進陵搏行探討的。從源碼、應用場景、基準性能、對比分析等幾個方面深入分析PHP之性能問題,並通過真實的數據來說話。
2.從原理分析PHP性能
從原理分析PHP的性能,主要從以下幾個方面:內存管理、變數、函數、運行機制來進行分析。
2.1內存管理
類似Nginx的內存管理方式,PHP在內部也是基於內存池,並且引入內存池的生命周期概念。在內存池方面,PHP對PHP腳本和擴展的所有內存相關操作都進行了託管。對大內存和小內存的管理採用了不同的實現方式和優化,具體可以參考以下文檔:
2.2變數
總所周知,PHP是一種弱變數類型的語言,所以在PHP內部,所有的PHP變數都對應成一種類型Zval,其中具體定義如下:
在變數方面,PHP做了大量的優化工作,比如說Reference counting和 on writer機制。這樣能夠保證內存使用上的優化,並且減少內存拷貝次數(請參考
2.3函數
在PHP內部,所有的PHP函數都回轉化成內部的一個函數指針。比如說擴展中函數
ZEND_FUNCTION(my_function);//類似functionmy_function(){}
在內部展開後就會是一個函數
voidzif_my_function(INTERNAL_FUNCTION_PARAMETERS);
voidzif_my_function(intht,
zval*return_value,
zval*this_ptr,
intreturn_value_used,
zend_executor_globals*executor_globals);
從這個角度來看,PHP函數在內部也是對應一個函數指針。
2.4運行機制
在話說PHP性能的時候,很多人都會說「C/C++是編譯型,JAVA是半編譯型,PHP是解釋型」。也就是說PHP是先動態解析再代碼運行的,所以從這個角度來看,PHP性能必然很差。
的確,從PHP腳本運行來輸出,的確是一個動態解析再代碼運行的過程。具體來說,PHP腳本的運行機制如下圖所示:
PHP的運行階段也分成三個階段:
Parse。語法分析階段。
Compile。編譯產出opcode中間碼。
Execute。運行,動態運行進行輸出。
所以說,在PHP內部,本身也是存在編譯的過程。並且據此產生了大量的opcode cache工具,比如說apc、eacc、xcache等等。這些opcode cache在生產環境基本上在標配。基於opcode cache,能到做到「PHP腳本編譯一次,多次運行」的效果。從這點上,PHP就和JAVA的半編譯機制非常類似。
所以,從運行機制上來看,PHP的運行模式和JAVA是非常類似的,都是先產生中間碼,然後運行在不同虛擬機上。
2.5動態運行
從上面的幾個分析來看,PHP在內存管理、變數、函數、運行機制等幾個方面都做了大量的工作,所以從原理來看,PHP不應該存在性能尺御祥問題,性能至少也應該和Java比較接近。
這個時候就不得不談PHP動態語言的特性所帶來的性能問題了,由於PHP是動態運行時,所以所有的變數、函數、對象調用、作用域實現等等都是在執行階段中才確定的。這個從根本上決定了PHP性能中很難改變的一些東西:在C/C++等拆蔽能夠在靜態編譯階段確定的變數、函數,在PHP中需要在動態運行中確定,也就決定了PHP中間碼不能直接運行而需要運行在Zend Engine上。
說到PHP變數的具體實現,又不得不說一個東西了:Hashtable。Hashtable可以說在PHP靈魂之一,在PHP內部廣泛用到,包含變數符號棧、函數符號棧等等都是基於hashtable的。
以PHP變數為例來說明下PHP的動態運行特點,比如說代碼:
?php
$var=「hello,」;
?
該代碼的執行結果就是在變數符號棧(是一個hashtable)中新增一個項
當要使用到該變數時候,就去變數符合棧中去查找(也就是變數調用對出了一個hash查找的過程)。
同樣對於函數調用也基本上類似有一個函數符號棧(hashtable)。
其實關於動態運行的變數查找特點,在PHP的運行機制中也能看出一些。PHP代碼通過解釋、編譯後的流程下圖:
從上圖可以看出,PHP代碼在compile之後,產出的了類符號表、函數符號表、和OPCODE。在真正執行的時候,zend Engine會根據op code去對應的符號表中進行查找,處理。
從某種程度上,在這種問題的上,很難找到解決方案。因為這是由於PHP語言的動態特性所決定的。但是在國內外也有不少的人在尋找解決方案。因為通過這樣,能夠從根本上完全的優化PHP。典型的列子有facebook的hiphop。
2.6結論
從上面分析來看,在基礎的內存管理、變數、函數、運行機制方面,PHP本身並不會存在明顯的性能差異,但由於PHP的動態運行特性,決定了PHP和其他的編譯型語言相比,所有的變數查找、函數運行等等都會多一些hash查找的CPU開銷和額外的內存開銷,至於這種開銷具體有多大,可以通過後續的基準性能和對比分析得出。
因此,也可以大體看出PHP不太適合的一些場景:大量計算性任務、大數據量的運算、內存要求很嚴格的應用場景。如果要實現這些功能,也建議通過擴展的方式實現,然後再提供鉤子函數給PHP調用。這樣可以減低內部計算的變數、函數等系列開銷。
3.基準性能
對於PHP基準性能,目前缺少標準的數據。大多數同學都存在感性的認識,有人認為800QPS就是PHP的極限了。此外,對於框架的性能和框架對性能的影響很沒有響應的權威數字。
本章節的目的是給出一個基準的參考性能指標,通過數據給大家一個直觀的了解。
具體的基準性能有以下幾個方面:
1.裸PHP性能。完成基本的功能。
2.裸框架的性能。只做最簡單的路由分發,只走通核心功能。
3.標准模塊的基準性能。所謂標准模塊的基準性能,是指一個具有完整服務模塊功能的基準性能。
3.1環境說明
測試環境:
Uname -aPnux db-forum-test17.db01..com 2.6.9_5-7-0-0 #1 SMP Wed Aug 12
17:35:51 CST 2009 x86_64 x86_64 x86_64 GNU/Pnux
Red Hat Enterprise Pnux AS release 4 (Nahant Update 3)
8 Intel(R) Xeon(R) CPU E5520 @ 2.27GHz
軟體相關:
Nginx:nginx version: nginx/0.8.54 built by gcc 3.4.5 20051201 (Red Hat 3.4.5-2)
Php5:(採用php-fpm)
PHP 5.2.8 (cP) (built: Mar 6 2011 17:16:18)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
with eAccelerator v0.9.5.3, Copyright (c) 2004-2006 eAccelerator, by eAccelerator
bingo2:
PHP框架。
其他說明:
目標機器的部署方式:nginx-php-fpm-php腳本。
測試壓力機器和目標機器獨立部署。
3.2裸PHP性能
最簡單的PHP腳本。
?php
require_once『./actions/indexAction.php』;
$objAction=newindexAction();
$objAction-init();
$objAction-execute();
?
Acitons/indexAction.php裡面的代碼如下
?php
classindexAction
{
pubPcfunctionexecute()
{
echo『hello,world!』;
}
}
?
通過壓力工具測試結果如下:
3.3裸PHP框架性能
為了和3.2的對比,基於bingo2框架實現了類似的功能。代碼如下
?php
require_once『Bingo/Controller/Front.php』;
$objFrontController=Bingo_Controller_Front::getInstance(array(『actionDir』=『./actions』,));
$objFrontController-dispatch();
壓力測試結果如下:
從該測試結果可以看出:框架雖然有一定的消耗,但對整體的性能來說影響是非常小的。
3.4標准PHP模塊的基準性能
所謂標准PHP模塊,是指一個PHP模塊所必須要具體的基本功能:
路由分發。
自動載入。
LOG初始化Notice日誌列印。所以的UI請求都一條標準的日誌。
錯誤處理。
時間校正。
自動計算每個階段耗時開銷。
編碼識別編碼轉化。
標准配置文件的解析和調用
採用bingo2的代碼自動生成工具產生標準的測試PHP模塊:test。
測試結果如下:
3.5結論
從測試數據的結論來看,PHP本身的性能還是可以的。基準性能完全能夠達到幾千甚至上W的QPS。至於為什麼在大多數的PHP模塊中表現不佳,其實這個時候更應該去找出系統的瓶頸點,而是簡單的說OK,PHP不行,那我們換C來搞吧。(下一個章節,會通過一些例子來對比,採用C來處理不見得有特別的優勢)
通過基準數據,可以得出以下幾個具體的結論:
1.PHP本身性能也很不錯。簡單功能下能夠達到5000QPS,極限也能過W。
2.PHP框架本身對性能影響非常有限。尤其是在有一定業務邏輯和數據交互的情況下,幾乎可以忽略。
3.一個標準的PHP模塊,基準性能能夠達到2000QPS(80 cpu idle)。
4.對比分析
很多時候,大家發現PHP模塊性能不行的時候,就來一句「ok,我們採用C重寫吧」。在公司內,採用C/C++來寫業務邏輯模塊的現象到處都有,在前幾年甚至幾乎全部都是採用C來寫。那時候大家寫的真是一個痛苦:調試難、敏捷不要談。

② php運行機制是什麼

PHP是一種純解釋型在服務端執行的可以內嵌HTML的腳本語言,尤其適合開發Web應用程序。
請求一個 PHP 腳本時,PHP 會讀取該腳本,並將其編譯為 Zend 操作碼,這是要執行的代碼的一種二進製表示形式。隨後,此操作碼由 PHP 執行並丟棄。 PHP腳本在每次被解釋時進行初始化,在解釋完畢後終止運行。這種運行是互相獨立的,每一次請求都會創建一個單獨的進程或線程,來解釋相應的頁面文件。頁面創建的變數和其他對象,都只在當前的頁面內部可見,無法跨越頁面訪問。在終止運行後,頁面中申請的、沒有被代碼顯式釋放的外部資源,包括內存、資料庫連接、文件句柄、Socket連接等,都會被強行釋放。也就是說,PHP無法在語言級別上實現直接訪問跨越頁面的變數,也無法創建駐留內存的對象。
PHP這種獨特的工作模型的優勢在於,基本上解決了令人頭疼的資源泄漏問題。Web應用的特點是大量的、短時間的並發處理,對各種資源的申請和釋放工作非常頻繁,很容易導致泄漏甚至崩潰。PHP的運行機制決定它不存在常規的崩潰問題(頂多連接超時腳本停止執行),可以說PHP是較穩定的Web應用。但是,這種機制的缺點也非常明顯。最直接的後果是,PHP在語言級別無法實現跨頁面的緩沖機制。這種緩沖機制缺失造成的影響,可以分成兩個方面:
一是對象的緩沖。眾所周知,很多設計模式都依賴於對象的緩沖機制,創建和銷毀對象是很費時間的,因為創建一個對象要獲取內存資源或者其它更多資源,對於需要頻繁應付大量並發的服務端軟體更是如此。因此,對象緩沖的缺失,理論上會極大地降低速度。應盡可能減少創建和銷毀對象的次數來提高服務程序的效率,由於 PHP目前還不支持多線程,也就無法像Java一樣通過線程池調度來彌補這一缺陷;但可以使用第三方軟體如Memcachd來實現PHP的對象緩沖機制,達到減少對象創建和銷毀的時間來提高服務程序的效率。Memcachd將PHP編譯後的 操作碼緩存並在內存中保存這個操作碼,並在下一次調用該頁面時重用它,這會節省很多時間。比較常用的緩存還有有 eAccelerator,另一種流行的 eAccelerator 替代工具是 Alternative PHP Cache(APC)。
二是資料庫連接的緩沖。對於MySQL,PHP提供了一種內置的資料庫緩沖機制,即用mysql_pconnect()代替mysql_connect() 來打開資料庫而已。PHP會自動回收被廢棄的資料庫連接,以供重復使用。在實際應用中,這種持久性資料庫連接往往會導致資料庫連接的偽泄漏現象:在某個時間,並發的資料庫連接過多,超過了MySQL的最大連接數,從而導致新的進程無法連接資料庫。但是過一段時間,當並發數減少時,PHP會釋放掉一些連接,網站又會恢復正常。出現這種現象的原因是,當使用pconnect時,Apache 的httpd進程會不釋放connect,而當Apache的httpd進程數超過了mysql的最大連接數時,就會出現無法連接的情況。因此,需要小心地調整Apache和Mysql的配置,以使Apache的httpd進程數不會超出MySQL的最大連接數。筆者經過實踐,在PHP5和 Oracle10g的連接中,由於頻於資料庫連接,有時候還會出現資料庫丟失連接的情況(Oracle官方有針對PHP的增強包,不知是否可以解決此問題,筆者未試)。
PHP的工作模型即是缺點也是優勢,從本質上說,這就是PHP 的獨特之處。
若以FastCGI模式運行php,解析php.ini、載入全部擴展並重初始化全部數據結構這些都只在進程啟動時發生一次。一個額外的好處是,持續資料庫連接可以工作。Nginx+PHP(FastCGI)是個不錯的選擇。

③ php在web上運行是多進程還是單進程

php在web上運行是單進程的,具體原因如下:
1、PHP是一個單線程的腳本開發語言,它常在Web開發及系統集成中出現。
PHP是單進程單線程的,當處理復雜的業務的時候我們會發現他串列執行命令的時候CPU、磁碟、內存等利用的都很低有很多時候都是在排隊等待,有的時候我們想並發的讓他去執行一批任務然後一起拿解決結果是一件很痛苦的事情(自己用pthread或者其他方式才能解決,但是這很痛苦)開發語言一直在升級變化適應需要。另外,可以考慮通訊使用Swoole。
2、解決方案如下:
分前後端,前端可以通過消息中間件,同步、非同步 調用一個或多個介面。但是socket的擴展確確實實不咋好用。不是普通小企業能做的出來的。

④ 如何獲得php當前的運行模式

PHP 獲取當前運行模式,使用php_sapi_name函數即可;示例如下:

<?php
$mod=php_sapi_name();
echo$mod;
//apache2handler
//PHP有多種運行模式,例如:apache、apache2filter、apache2handler、caudium、cgi
//cgi-fcgi、cli、cli-server、continuity、embed、fpm-fcgi等等。?>

⑤ 請問php在apache下運行有幾種模式,區別是什麼該怎樣設置,謝謝

Windows 下有兩種方法使 PHP 工作於 Apache 2.0.x 之中。一種是 使用 CGI 可執行程序,另一種是適用 Apache 模塊的 DLL。不管哪種都需要編輯 httpd.conf 來配置 Apache 支持 PHP 並重新啟動伺服器。

注: 記住在 Windows 下給 Apache 的配置文件中加入路徑值的時候,所有的反斜線例如 c:\directory\file.ext 必須轉換成正斜線,如 c:/directory/file.ext。

以 CGI 方式安裝
需要將以下三行加入到 Apache 的 httpd.conf 配置文件中以設定 CGI: 例子 6-5. PHP 在 Apache 2.0 中的 CGI 方式

ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php .php

# 對 PHP 4 用這行
Action application/x-httpd-php "/php/php.exe"

# 對 PHP 5 用這行
Action application/x-httpd-php "/php/php-cgi.exe"

警告
如果使用 CGI 方式安裝,則伺服器對於某些可能的攻擊是開放的。請閱讀 CGI 安全一章以學習如何防禦這些攻擊。

以 Apache 模塊方式安裝
需要將以下兩行加入到 Apache 的 httpd.conf 配置文件中以設定 Apache 2.0 的 PHP 模塊: 例子 6-6. PHP 在 Apache 2.0 中的模塊方式

# 對 PHP 4 用這兩行:
LoadMole php4_mole "c:/php/php4apache2.dll"
# 別忘了從 sapi 目錄中把 php4apache2.dll 拷貝出來!
AddType application/x-httpd-php .php

# 對 PHP 5 用這兩行:
LoadMole php5_mole "c:/php/php5apache2.dll"
AddType application/x-httpd-php .php

# 配置 php.ini 的路徑
PHPIniDir "C:/php"

注: 記得用自己 PHP 實際所在的路徑替換掉上例中的 c:/php/。要留意在 LoadMole 指令中用的是 php4apache2.dll 或 php5apache2.dll,而不是 php4apache.dll 或 php5apache.dll,後者是設計用於 Apache 1.3.x 的。

注: 如果要使用內容協商機制,請閱讀有關 FAQ。

警告
不要在安裝中混合使用來自不同 PHP 版本的 DLL。使用下載回來的 PHP 版本中所提供的 DLL 和擴展庫是唯一選擇。

閱讀全文

與判斷php運行模式相關的資料

熱點內容
遞歸編程與數學應用 瀏覽:928
驚變1小時8分鍾才是經典 瀏覽:724
ps如何pdf製作 瀏覽:782
如何按照序號排列文件夾 瀏覽:433
演算法設計與分析基礎網盤 瀏覽:712
linux信號量的使用 瀏覽:61
朴初炫演過的電影 瀏覽:969
掌閱下的書在哪個文件夾 瀏覽:851
程序員學python難嗎 瀏覽:737
源泉插件圖紙加密 瀏覽:609
minitab編程 瀏覽:231
網頁編程語言大全 瀏覽:633
單片機鋰離子 瀏覽:9
單片機交流電流測量 瀏覽:717
小雞模擬器ios游戲一直正在解壓 瀏覽:928
可以把文件夾轉化為文檔的軟體 瀏覽:956
微軟認證高級程序員 瀏覽:887
人工智慧網路演算法工程師 瀏覽:459
白色邊框app是什麼 瀏覽:740
日本愛情尺寸度電影推薦 瀏覽:935