PHP 下要做 Socket 多工目前只有 select 或用超慢的 fork 方式 , 但學過 Socket Programing 的人都知道 select 在大量連線下的效能會很差 , 而在很早之前我曾在 PECL 看見有個 event 的 extension 是利用 Kernel 來處理 I/O 事件 , 舉凡 File , Socket 都可, 當時那套 event extension 是利用 Linux epoll 或 FreeBSD kqueue 的 Kernel API 直接幹的 , 現在則有另一套 libevent 的 extension 出現在 PECL 上 , 這個 extension 就是用同名 C 寫的 libevent 去實做 , libevent 也是會用到 epoll 及 kqueue 但提供了一組函數介面讓程式設計師不用去管 OS 是什就可以設計出高效能的多工程式 , 因此我特地抓下來玩一玩 , 並且寫了簡單的性能測試
由於 PHP libevent 需要搭配C 的 libevent 1.4 以上版本 , 所以並非每個 Linux 套件都有 , 例如我的 CentOS 的 libevent 版本就比較舊 , 因此要自行編譯 , 以下就說明 CentOS 5.4 下成功編譯 PHP libevent 的步驟
必要套件 :
- 官網下載 libevent-1.4 source code : http://www.monkey.org/~provos/libevent/
- PECL 下載 libevent extension : http://pecl.php.net/package/libevent
- re2c 0.13 : 可先安裝 rpmforge 的 yum repo : 可看這 https://www.pigo.idv.tw/archives/242 , 然後以 yum install re2c 安裝
- PHP 5.2.1 以上 , php-devel 套件也要裝
編譯步驟
1. 編譯 libevent
解開 libevent source code , 進入 source code 目錄
執行 ./configure --prefix=/usr/local
執行 make
執行 make install
2. 編譯 PHP libevent
解開 PHP libevent source code , 進入 source code 目錄
執行 phpize
執行 ./configure --with-libevent=/usr/local
執行 make
執行 make install
這樣會把 libevent.so 安裝到 /usr/lib/php/modoules 或 /usr/lib64/php/modules , 看 os 是 32bit 或 64bit
測試
我寫了兩個 php script , 分別用 select 及 libevent 實做出模擬簡單的 HTTP Server , 並且用 ab 來測試性能 , 每次測試大量連線跑 10 萬次的時間 , 數據如下
Connections | select | libevent |
100 | 10.656 | 9.298 |
500 | 11.175 | 9.791 |
800 | 17.327 | 9.709 |
1000 | 23.282 | 9.749 |
這個測試是使用 ab -c nnn -n 100000 -k http://n.n.n.n:8888/ 去測試的 , 可以發現到 , select 模式當連線越多的時候 , 效能降低的非常嚴重 , 學過 Socket 程式設計的人應該知道 select 是屬於輪詢方式來檢查所有連線是否有資料異動 , 而 libevent 則會用到 os 的特異功能 , 如 Linux 下有 epoll , FreeBSD 下有 kqueue , 這些特異功能是 kernel 的呼叫 , 由 kernel 負責監控 , 然後發出事件給應用程式 , 所以效能的差異非常明顯 , 現在 PHP 有了 libevent 之後 , 也許未來會有許多Server應用可以用 PHP 快速寫出來
有興趣研究的人可以下載我所寫的 sample , 裡面有說明 README.TXT 如何啟動兩種 Server
下載點 : http://testcode.pigo.idv.tw/simplehttpd.tar.gz
2013-11-27 補充說明
由於此篇文章很久前寫的,已不適用於現在的環境,目前 PHP 中有個叫 event 的 extension 是目前有持續在維護的,libevent 已經停止開發了,有興趣的玩家可參閱以下兩個 LINK
- PECL 的 event : http://pecl.php.net/package/event
- event 文件 : http://docs.php.net/event
您好,文章提供的下载连接已经无法下载,能否发我一份,最近正好在研究这个。不胜感激~
可以下載啊 !
麻烦修复下载链接,谢谢~
hi , 現在 libevent 已經沒有維護了
取而代之的是 php-event
你可以參考 https://www.pigo.idv.tw/archives/1858 ,這裡頭有提供範例也是可以看的