php高階學習交流qq群:983229225
事務的概念
一提到高併發,就沒有辦法繞開i/o復用,再具體到特定的平台linux, 就沒辦法繞開epoll. epoll為啥高效的原理就不講了,感興趣的同學可以自行搜尋研究一下。
php怎麼玩epoll?首先得安裝個libevent庫,再裝個event擴充套件或者libevent擴充套件就可以愉快地玩耍了。
有些人搞不清楚libevent庫跟libevent擴充套件的區別,簡單來說,libevent庫是c語言對epoll的封裝,跟php毛關係都沒有;libevent擴充套件就是php跟libevent庫的溝通橋梁。實際上php的很多擴充套件就是幹這個事的,有一些優秀的c語言庫,php想直接拿來用,就通過php擴充套件的方式接入到php。
libevent擴充套件和event擴充套件隨便選乙個裝,我個人更喜歡event擴充套件,因為更物件導向一點。自己去裡面搜跟自己php版本對應的擴充套件,下好編譯安裝一下就ok了.電腦裝了多個版本的php編譯的時候注意一下,phpize的版本要對應上,別搞錯了,典型的五步曲:
我們要實現的伺服器,傳輸層是tcp協議,應用層協議太多太複雜,限於篇幅,會簡單地以http伺服器舉個例子,http協議本身就很複雜,要實現起來細節上有很多考究,我們也不會完全實現http協議。
首先,建立乙個socket,三步曲,socket_create、socket_bind、socket_listen,為什麼是這三步曲呢?很簡單,不管你傳輸層協議是啥,你下面的網路層協議你得選個版本吧,ipv4還是ipv6,傳輸層工作方式你得選乙個吧,全雙工、半雙工還是單工,tcp還是udp你也得選乙個吧,socket_create就是這三個選項;確定了網路層和傳輸層,你得告訴我監聽哪個埠吧,這就對應了socket_bind;然後你得開啟監聽,並指定乙個客戶端的佇列長度吧,這就是socket_listen幹的事。
建立完了,同步阻塞咱就不介紹了,乙個程序同時最多hold處乙個連線,多幾個連線同時請求,就得等唄,超過了socket_listen指定的佇列長度,就得返回504了。多程序也一樣,幾個程序就有幾個併發,程序又是昂貴資源,而且程序的上下文切換費時費力,導致整個系統效率低下。
沒關係,咱有epoll,hold住萬千請求不是夢,先實現乙個reactor。libevent庫就是reactor模式,直接呼叫函式就是在使用reactor模式,所以無需糾結到底php怎麼實現reactor模式。
上面的**很簡單,簡單解釋一下概念,eventbase就是個容器,裡面裝的event例項,這麼一說,上面的**就非常好懂了。然後乙個server。
先建立socket的三步曲,設定成非阻塞模式。然後把socket加到reactor中監聽可讀事件,可讀的意思就是,緩衝區有資料了,才可讀。可讀事件發生,說明有新連線來了,用stream_socket_accept接收新連線conn,把conn放到reactor中監聽可讀事件,可讀事件發生,說明客戶端有資料傳送過來了,迴圈讀直到沒資料,然後把conn放到reactor中監聽可寫事件,可寫事件發生,說明客戶端資料傳送完了,把協議組裝一下寫入響應。
應用層如果是http協議要注意一下connection: keep-alive頭,因為要復用連線,不要一寫完就關閉連線。
擼完收工,用ab測一下併發,加-k引數復用連線,i5+8g,3w的併發沒啥問題,當然我們這兒沒有磁碟i/o,實際情況要從磁碟讀取檔案,讀檔案要通過linux的系統呼叫,而且有幾次的檔案拷貝操作,花銷比較大,常用的解決思路是sendfile,零拷貝直接從乙個fd到另乙個fd,效率比較高,缺點就是php沒有現成的已經實現sendfile的擴充套件,得自己動手,開發成本有點高。
ab測試po圖:
這就是php實現高併發伺服器的思路了,只要是用epoll解決的,思路都一樣,都是三步曲,放到reactor下監聽fd事件。當然這個只是最簡單的模型,還有很多可以改進的地方,比如說多程序,抄襲一下nginx,乙個主程序+n個工作程序,多程序的目的還是想利用多核並行工作。
c語言實現也是這樣,只是你可能不用libevent庫,自己封裝epoll,畢竟libevent庫有點重,你也用不到libevent的很多東西;當然了,c語言有一堆的資料結構以及定義在資料結構上的操作要寫,沒有gc,自己管理記憶體,還要有良好的設計,上多程序還得搞一搞ipc程序間通訊的東西,開發難度比php要大地多,開發周期也很長,有興趣的同學可以自己擼乙個玩。
繼續原味之旅
還記得 原味 這兩隻充滿靈感 永遠向前的 蟲子嗎?自從上個月向大家介紹他們之後,我自己一直都陶醉於他們所營造的純粹自然的 氛圍 沒有功利,只有對 最為本源的追逐。這段時間,我經常都在聽他們的主打歌 原味 每次都會被歌曲的清新真摯所打動,聽得越多則越是為之感動。就在自己沉醉於 原味 之中的時候,原味 ...