php的生命周期
① 怎麼理解php Session的用法 生命周期 過期時間
session簡介
Session直接翻譯成中文比較困難,一般都譯成時域。在計算機專業術語中,Session是指一個終端用戶與交互系統進行通信的時間間隔,通常指從注冊進入系統到注銷退出系統之間所經過的時間以及如果需要的話,可能還有一定的操作空間。
具體到Web中的Session指的就是用戶在瀏覽某個網站時,從進入網站到瀏覽器關閉所經過的這段時間,也就是用戶瀏覽這個網站所花費的時間。因此從上述的定義中我們可以看到,Session實際上是一個特定的時間概念。
需要注意的是,一個Session的概念需要包括特定的客戶端,特定的伺服器端以及不中斷的操作時間。A用戶和C伺服器建立連接時所處的Session同B用戶和C伺服器建立連接時所處的Session是兩個不同的Session。
② asp.net 高手過來領分啦,急,急
主要分伺服器的安全 程序的安全
伺服器的安全 扯遠了,你去相關論壇都能找到 關閉不必要埠服務等等。。。
程序的安全
主要有資料庫的安全,比如sql注入 mdb文件安全 寫相關資料庫語句的時候注意一下就行了
還有就是上傳文件的地方,做好處理,防止非法用戶上傳木馬 提權
想到的就這些了,對應著搜索一下看看如何詳細處理就行了
③ PHP的性能探討和測試
緣起
關於PHP 很多人的直觀感覺是PHP是一種靈活的腳本語言 庫類豐富 使用簡單 安全 非常適合WEB開發 但性能低下 PHP的性能是否真 的就如同大家的感覺一樣的差呢?本文就是圍繞這么一個話題來進行探討的 從源碼 應用場景 基準性能 對比分析等幾個方面深入分析PHP之性能問題 並通 過真實的數據來說話
從原理分析PHP性能
從原理分析PHP的性能 主要從以下幾個方面 內存管理 變數 函數 運行機制來進行分析
內存管理
類似Nginx的內存管理方式 PHP在內部也是基於內存池 並且引入內存池的生命周期概念 在內存池方面 PHP對PHP腳本和擴展的所有內 存相關操作都進行了託管 對大內存和小內存的管理採用了不同的實現方式和優化 具體可以參考以下文檔 在內存分配和回收的生命周期內 PHP採用一次初始化申請+動態擴容+內存標識回收機制 並且在每次請求結束後直 接對內存池進行重新mask
變數
總所周知 PHP是一種弱變數類型的語言 所以在PHP內部 所有的PHP變數都對應成一種類型Zval 其中具體定義如下
圖一PHP變數
在變數方面 PHP做了大量的優化工作 比如說Reference counting和 on writer機制 這樣能夠保證內存使用上的優化 並且亮簡逗減少內存拷貝次數(請參考) 在數組方面 PHP內部採用高效的hashtable來實現
函數
在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函數在內部也是對應一個函數指針
運行機制
敬賣在話說PHP性能的時候 很多人都會說「C/C++是編譯型咐李 JAVA是半編譯型 PHP是解釋型」 也就是說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是非常類似的 都是先產生中間碼 然後運行在不同虛擬機上
動態運行
從上面的幾個分析來看 PHP在內存管理 變數 函數 運行機制等幾個方面都做了大量的工作 所以從原理來看 PHP 不應該存在性能問題 性能至少也應該和Java 比較接近
這個時候就不得不談PHP動態語言的特性所帶來的性能問題了 由於PHP是動態運行時 所以所有的變數 函數 對象調用 作用域實現等等都是在 執行階段中才確定的 這個從根本上決定了PHP性能中很難改變的一些東西 在C/C++等能夠在靜態編譯階段確定的變數 函數 在PHP中需要在動態運行 中確定 也就決定了PHP中間碼不能直接運行而需要運行在Zend Engine上
說到PHP變數的具體實現 又不得不說一個東西了 Hashtable Hashtable可以說在PHP靈魂之一 在PHP內部廣泛用到 包含變數符號棧 函數符號棧等等都是基於hashtable的
以PHP變數為例來說明下PHP的動態運行特點 比如說代碼
<?php
$var=「hello blog xiuwz 」;
?>
該代碼的執行結果就是在變數符號棧(是一個hashtable)中新增一個項
當要使用到該變數時候 就去變數符合棧中去查找(也就是變數調用對出了一個hash查找的過程)
同樣對於函數調用也基本上類似有一個函數符號棧(hashtable)
其實關於動態運行的變數查找特點 在PHP的運行機制中也能看出一些 PHP代碼通過解釋 編譯後的流程下圖
圖 PHP運行實例
從上圖可以看出 PHP代碼在pile之後 產出的了類符號表 函數符號表 和OPCODE 在真正執行的時候 zend Engine會根據op code去對應的符號表中進行查找 處理
從某種程度上 在這種問題的上 很難找到解決方案 因為這是由於PHP語言的動態特性所決定的 但是在國內外也有不少的人在尋找解決方案 因為 通過這樣 能夠從根本上完全的優化PHP 典型的列子有facebook的hiphop
結論
從上面分析來看 在基礎的內存管理 變數 函數 運行機制方面 PHP本身並不會存在明顯的性能差異 但由於PHP的動態運行特性 決定了 PHP和其他的編譯型語言相比 所有的變數查找 函數運行等等都會多一些hash查找的CPU開銷和額外的內存開銷 至於這種開銷具體有多大 可以通過後 續的基準性能和對比分析得出
因此 也可以大體看出PHP不太適合的一些場景 大量計算性任務 大數據量的運算 內存要求很嚴格的應用場景 如果要實現這些功能 也建議通過擴展的方式實現 然後再提供鉤子函數給PHP調用 這樣可以減低內部計算的變數 函數等系列開銷
基準性能
對於PHP基準性能 目前缺少標準的數據 大多數同學都存在感性的認識 有人認為 QPS就是PHP的極限了 此外 對於框架的性能和框架對性能的影響很沒有響應的權威數字
本章節的目的是給出一個基準的參考性能指標 通過數據給大家一個直觀的了解
具體的基準性能有以下幾個方面
裸PHP性能 完成基本的功能
裸框架的性能 只做最簡單的路由分發 只走通核心功能
標准模塊的基準性能 所謂標准模塊的基準性能 是指一個具有完整服務模塊功能的基準性能
環境說明
測試環境
Uname aPnux db forum test db _ # SMP Wed Aug : : CST x _ x _ x _ GNU/PnuxRed Hat Enterprise Pnux AS release (Nahant Update )
Intel(R) Xeon(R) CPU E @ GHz
軟體相關
Nginx nginx version: nginx/ built by gcc (Red Hat )Php (採用php fpm)
PHP (cP) (built: Mar : : )
Copyright (c) The PHP Group
Zend Engine v Copyright (c) Zend Technologies
with eAccelerator v Copyright (c) eAccelerator by eAccelerator
bingo
PHP框架
其他說明
目標機器的部署方式 nginx >php fpm >php腳本
測試壓力機器和目標機器獨立部署
裸PHP性能
最簡單的PHP腳本
<?php
require_once『 /actions/indexAction php』;
$objAction=newindexAction();
$objAction >init();
$objAction >execute();
?>
Acitons/indexAction php裡面的代碼如下
<?php
classindexAction
{
pubPcfunctionexecute()
{
echo『hello world!』;
}
}
?>
通過壓力工具測試結果如下
裸PHP框架性能
為了和 的對比 基於bingo 框架實現了類似的功能 代碼如下
<?php
require_once『Bingo/Controller/Front php』;
$objFrontController=Bingo_Controller_Front::getInstance(array(
『actionDir』=>『 /actions』
));
$objFrontController >dispatch();
壓力測試結果如下
從該測試結果可以看出 框架雖然有一定的消耗 但對整體的性能來說影響是非常小的
標准PHP模塊的基準性能
所謂標准PHP模塊 是指一個PHP模塊所必須要具體的基本功能
路由分發
自動載入
LOG初始化&Notice日誌列印 所以的UI請求都一條標準的日誌
錯誤處理
時間校正
自動計算每個階段耗時開銷
編碼識別&編碼轉化
標准配置文件的解析和調用
採用bingo 的代碼自動生成工具產生標準的測試PHP模塊 test
測試結果如下
結論
從測試數據的結論來看 PHP本身的性能還是可以的 基準性能完全能夠達到幾千甚至上W的QPS 至於為什麼在大多數的PHP模塊中表現不佳 其實這個時候更應該去找出系統的瓶頸點 而是簡單的說OK PHP不行 那我們換C來搞吧 (下一個章節 會通過一些例子來對比 採用C來處理不見得有特 別的優勢)
通過基準數據 可以得出以下幾個具體的結論
PHP本身性能也很不錯 簡單功能下能夠達到 QPS 極限也能過W
PHP框架本身對性能影響非常有限 尤其是在有一定業務邏輯和數據交互的情況下 幾乎可以忽略
一個標準的PHP模塊 基準性能能夠達到 QPS( cpu idle)
對比分析
lishixin/Article/program/PHP/201311/21287
④ websocket簡介
WebSocket是HTML5出的東西(協議),也就是說HTTP協議沒有變化,或者說沒關系,但HTTP是不支持持久連接的(長連接,循環連接的不算)
首先HTTP有 1.1 和 1.0 之說,也就是所謂的 keep-alive,把多個HTTP請求合並為一個,但是 Websocket 其實是一個新協議,跟HTTP協議基本沒有關系,只是為了兼容現有瀏覽器的握手規范而已,也就是說它是HTTP協議上的一種補充
他們有交集,但是並不是全部。
另外Html5是指的一系列新的API,或者說新規范,新技術。Http協議本身只有1.0和1.1,而且跟Html本身沒有直接關系。。通俗來說,你可以用HTTP協議傳輸非Html數據,就是這樣=。=
再簡單來說,層級不一樣。
首先,Websocket是一個持久化的協議,相對於HTTP這種非持久的協議來說。簡單的舉個例子吧,用目前應用比較廣泛的PHP生命周期來解釋。
HTTP的生命周期通過 Request 來界定,也就是一個 Request 一個 Response ,那麼在 HTTP1.0 中,這次HTTP請求就結束了。
在HTTP1.1中進行了改進,使得有一個keep-alive,也就是說,在一個HTTP連接中,可以發送多個Request,接收多個Response。但是請記住 Request = Response , 在HTTP中永遠是這樣,也就是說一個request只能有一個response。而且這個response也是被動的,不能主動發起。
教練,你BB了這么多,跟Websocket有什麼關系呢? (:з」∠) 好吧,我正准備說Websocket呢。。
首先Websocket是基於HTTP協議的,或者說借用了HTTP的協議來完成一部分握手。
首先我們來看個典型的 Websocket 握手(借用Wikipedia的。。)
熟悉HTTP的童鞋可能發現了,這段類似HTTP協議的握手請求中,多了幾個東西。我會順便講解下作用。
這個就是Websocket的核心了,告訴 Apache 、 Nginx 等伺服器:注意啦,我發起的是Websocket協議,快點幫我找到對應的助理處理~不是那個老土的HTTP。
首先, Sec-WebSocket-Key 是一個 Base64 encode 的值,這個是瀏覽器隨機生成的,告訴伺服器:泥煤,不要忽悠窩,我要驗證尼是不是真的是Websocket助理。
然後, Sec_WebSocket-Protocol 是一個用戶定義的字元串,用來區分同URL下,不同的服務所需要的協議。簡單理解:今晚我要服務A,別搞錯啦~
最後, Sec-WebSocket-Version 是告訴伺服器所使用的 Websocket Draft(協議版本),在最初的時候,Websocket協議還在 Draft 階段,各種奇奇怪怪的協議都有,而且還有很多期奇奇怪怪不同的東西,什麼Firefox和Chrome用的不是一個版本之類的,當初Websocket協議太多可是一個大難題。。不過現在還好,已經定下來啦 大家都使用的一個東西 脫水: 服務員,我要的是13歲的噢→_→
然後伺服器會返回下列東西,表示已經接受到請求, 成功建立Websocket啦!
這里開始就是HTTP最後負責的區域了,告訴客戶,我已經成功切換協議啦~
Upgrade: websocket
Connection: Upgrade
依然是固定的,告訴客戶端即將升級的是 Websocket 協議,而不是mozillasocket,lurnarsocket或者shitsocket。
然後, Sec-WebSocket-Accept 這個則是經過伺服器確認,並且加密過後的 Sec-WebSocket-Key 。 伺服器:好啦好啦,知道啦,給你看我的ID CARD來證明行了吧。。
後面的, Sec-WebSocket-Protocol 則是表示最終使用的協議。
至此,HTTP已經完成它所有工作了,接下來就是完全按照Websocket協議進行了。具體的協議就不在這闡述了。
——————技術解析部分完畢——————
你TMD又BBB了這么久,那到底Websocket有什麼鬼用, http long poll ,或者ajax輪詢 不都可以實現實時信息傳遞么。
好好好,年輕人,那我們來講一講Websocket有什麼用。來給你吃點胡(蘇)蘿(丹)卜(紅)
在講Websocket之前,我就順帶著講下 long poll 和 ajax輪詢 的原理。
ajax輪詢
ajax輪詢的原理非常簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問伺服器是否有新信息。
場景再現:
long poll
long poll 其實原理跟 ajax輪詢 差不多,都是採用輪詢的方式,不過採取的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,客戶端發起連接後,如果沒消息,就一直不返回Response給客戶端。直到有消息才返回,返回完之後,客戶端再次建立連接,周而復始。
場景再現:
從上面可以看出其實這兩種方式,都是在不斷地建立HTTP連接,然後等待服務端處理,可以體現HTTP協議的另外一個特點,被動性。
何為被動性呢,其實就是,服務端不能主動聯系客戶端,只能有客戶端發起。
簡單地說就是,伺服器是一個很懶的冰箱(這是個梗)(不會、不能主動發起連接),但是上司有命令,如果有客戶來,不管多麼累都要好好接待。
說完這個,我們再來說一說上面的缺陷(原諒我廢話這么多吧OAQ)
從上面很容易看出來,不管怎麼樣,上面這兩種都是非常消耗資源的。
ajax輪詢 需要伺服器有很快的處理速度和資源。(速度)long poll 需要有很高的並發,也就是說同時接待客戶的能力。(場地大小)
所以 ajax輪詢 和 long poll 都有可能發生這種情況。
言歸正傳,我們來說Websocket吧
通過上面這個例子,我們可以看出,這兩種方式都不是最好的方式,需要很多資源。
一種需要更快的速度,一種需要更多的』電話』。這兩種都會導致』電話』的需求越來越高。
哦對了,忘記說了HTTP還是一個狀態協議。
通俗的說就是,伺服器因為每天要接待太多客戶了,是個健忘鬼,你一掛電話,他就把你的東西全忘光了,把你的東西全丟掉了。你第二次還得再告訴伺服器一遍。
所以在這種情況下出現了,Websocket出現了。他解決了HTTP的這幾個難題。首先,被動性,當伺服器完成協議升級後(HTTP->Websocket),服務端就可以主動推送信息給客戶端啦。所以上面的情景可以做如下修改。
就變成了這樣,只需要經過一次HTTP請求,就可以做到源源不斷的信息傳送了。(在程序設計中,這種設計叫做回調,即:你有信息了再來通知我,而不是我傻乎乎的每次跑來問你 )
這樣的協議解決了上面同步有延遲,而且還非常消耗資源的這種情況。那麼為什麼他會解決伺服器上消耗資源的問題呢?
其實我們所用的程序是要經過兩層代理的,即HTTP協議在Nginx等伺服器的解析下,然後再傳送給相應的Handler(PHP等)來處理。簡單地說,我們有一個非常快速的 接線員(Nginx) ,他負責把問題轉交給相應的 客服(Handler) 。
本身接線員基本上速度是足夠的,但是每次都卡在客服(Handler)了,老有客服處理速度太慢。,導致客服不夠。Websocket就解決了這樣一個難題,建立後,可以直接跟接線員建立持久連接,有信息的時候客服想辦法通知接線員,然後接線員在統一轉交給客戶。
這樣就可以解決客服處理速度過慢的問題了。
同時,在傳統的方式上,要不斷的建立,關閉HTTP協議,由於HTTP是非狀態性的,每次都要重新傳輸 identity info (鑒別信息),來告訴服務端你是誰。
雖然接線員很快速,但是每次都要聽這么一堆,效率也會有所下降的,同時還得不斷把這些信息轉交給客服,不但浪費客服的處理時間,而且還會在網路傳輸中消耗過多的流量/時間。
但是Websocket只需要一次HTTP握手,所以說整個通訊過程是建立在一次連接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求,這樣就解決了接線員要反復解析HTTP協議,還要查看identity info的信息。
同時由客戶主動詢問,轉換為伺服器(推送)有信息的時候就發送(當然客戶端還是等主動發送信息過來的。。),沒有信息的時候就交給接線員(Nginx),不需要佔用本身速度就慢的客服(Handler)了
——————–
至於怎麼在不支持Websocket的客戶端上使用Websocket。。答案是: 不能
但是可以通過上面說的 long poll 和 ajax 輪詢 來 模擬出類似的效果