FROM : http://www.csdn.net/article/2015-10-12/2825887
摘要:ReactPHP作為Node.js的PHP版本。在實現思路,使用方法,應用場景上的確有很多相似之處。但是ReactPHP畢竟比Node.js年輕,目前生態圈還是不如Node.js完善。目前文檔也不是很完善,在國內應用也比較少。
從名字說起
雖然ReactPHP項目已經發展了有4年之久,但是對於其稱呼顯得有點混亂。在開源中國為其建立的項目主頁上,其被命名為React,或者node.PHP。國外的一些的博客談及這個項目時,多數使用的是ReactPHP。到底哪種說法比較標准呢?我們不妨來看看官方的態度。此項目的官方主頁是http://www.reactphp.org。打開官網,你會發現網站的title是React,其logo上的文字為reactphp。可以看出,官方更傾向於被命名為React或者ReactPHP。我建議使用ReactPHP作為其名稱。原因大概有兩個。
- React單詞的意思太泛,並且已經有一些項目的名稱與React相關,容易引起誤解。
- 目前國內使用ReactPHP的人比較少,相關資料文檔也比較少。在國外它一般被稱為ReactPHP,使用ReactPHP在國外檢索資料更容易。
ReactPHP與Node.js有着相同的特點
許多人認為ReactPHP是Node.js的php版本,這是有一定道理的。他們的確有很多相似的特點。
事件驅動,異步執行,非阻塞IO
什么是事件驅動?所謂事件驅動,簡單的說就是,你告訴我你關注什么事情,等事情發生的時候我會主動通知你,然后你再作相應的處理。這樣可以就可以把你解放出來,你只關注於處理好相應事件即可。采用事件驅動有什么優勢呢?相對於常見的多進程編程,能更好的利用CPU資源。多進程編程會使進程數量變多,進程上下文切換頻繁會增加系統壓力,浪費寶貴的CPU資源。相對於多線程編程而言,可以降低編程復雜度。開發者不必再考慮線程間資源共享導致資源競爭等問題。
ReactPHP和Node.js都采用了事件驅動和非阻塞IO。從官方主頁的宣傳語上就可以得到印證。在Node.js的官網上有一段話:
Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient。
上面的意思是,Node.js使用事件驅動和非阻塞IO模型,以保證輕量級和高效。
在ReactPHP官網也有一段話:
Event-driven, non-blocking I/O with PHP.
上面的意思是,ReactPHP使用PHP語言實現了事件驅動和非阻塞。
ReactPHP和Node.js在實現事件驅動機制時也有相似之處。在事件的監聽上,ReactPHP和Node.js都使用了libev庫,但是也都是不只使用libev庫。由於libev對windows支持不夠好。因此,Node.js中封裝了一層libuv。libuv是基於windows的IOCP和*nix的libev進行封裝。而ReactPHP除了使用libev庫外,還是用了其他的庫。如,libevent。
ReactPHP和Node.js都各自有自己的生態圈。在各自生態圈中的一些模塊一般都采用了事件驅動,異步編程的風格。如,ReactPHP的Stream模塊,提供了以下幾個事件:drain、error、close、pipe、end、data。相應的,在Node.js中也有一些類似的事件。Node.js的Net模,其中的net.Socket對象就有以下事件:connect、data、end、timeout、drain、error、close等。這樣,開發人員只需要知道自己關注那些事件,並在這些事件上注冊回調函數。等事件發生的時候,會主動執行這些注冊的回調函數。這些回調函數都是異步執行的,這些函數雖然在注冊的時候有先后順序,但是在執行的時候是無序的,隨機的,執行順序和事件發生順序相關。事件驅動再加上非阻塞IO,就可以極大的利用系統資源,代碼無需阻塞等待資源可用。
單進程單線程
ReactPHP和Node.js一樣都是采用了單進程和單線程的運行方式。單進程,單線程方式,沒有多線程的資源搶占和上下文切換,高效率的運行,維護着一個事件隊列。這種運行方式,通常情況下瓶頸一般在CPU而不是內存。由於單進程,單線程只能在一個CPU上運行,本身不能充分利用多個CPU資源。為了解決這個問題,我們可以啟動多個進程,監聽不同的端口,前端使用nginx等做代理,把請求分發到不同的進程上。對於多進程的管理上,現在已經有不少開源項目可以實現。如,php-pm(https://github.com/php-pm/php-pm)。
ReactPHP性能壓測
相對於傳統的nginx+php-fpm方式,ReactPHP的性能表現如何呢?現在我們來做下性能壓測。服務器環境如下:
- 8核CPU
- PHP版本為5.5.15,使用opcache擴展
- 操作系統為Centos5
- Nginx版本為nginx/1.2.9
- ReactPHP版本為0.4
為了公平起見,我們php-fpm和ReactPHP都只啟動一個進程。壓測工具我們使用ab,Apache開源的http服務壓測工具。我們壓測分兩種情況來進行:第一種情況是只輸出簡單的Hello World。第二種情況只進行一次簡單的sql語句查詢,select 1 as num。
第一種情況:Hello World的壓測結果如下,QPS:
第二種情況:SQL查詢的壓測結果如下,QPS:
可見,對於cpu密集型的應用,nginx+php-fpm的方式要比ReactPHP有更好的表現。但是對於數據庫查詢這樣涉及網絡IO的場景,ReactPHP的性能要遠遠好於nginx+php-fpm的方式。
ReactPHP的應用場景
根據上面的測試,ReactPHP更適合IO密集型的應用。以下是ReactpHP比較適合的應用場景。
- 從RESTful API獲取數據,並進行拼裝輸出只是請求api獲取數據,然后進行簡單的拼裝,最后輸出到客戶端。本身業務邏輯不復雜。在請求的時候,可以同時對多個api進行請求,相對於順序調用api的方式,會節省很多的時間,大大提高了響應的效率。
- 實時推送,在線聊天實時推送和在線聊天都需要維護大量的鏈接。這個正是ReactpHP擅長的。他可以很輕松的維護上萬的鏈接。
- 分布式IO系統如一個數據庫中間件層,它需要解析SQL為多條子SQL,然后把子SQL分發到不同的服務器查詢數據,然后合並數據返回給客戶端。這種情況下可以使用ReactPHP同時對多個數據庫服務器進行查詢。
如何使用ReactPHP
ReactPHP可以使用composer安裝,這個也是官方推薦的安裝方式。首先安裝composer。
curl -s https://getcomposer.org/installer
| php
安裝完成后,會在當前目錄下生成一個composer.phar文件。然后我們使用composer.phar安裝react。
php ./composer.phar require react/react
安裝成功后,會在當前目錄下生成一個vendor目錄。下載的程序就在這個目錄下。現在你就可以使用ReactPHP寫程序了。例如,我們想提供一個http服務,我們將把客戶端通過data參數提交的數據加上www.后進行返回。代碼如下:
<?php require 'vendor/autoload.php'; $port = $argv[1]; $app = function ($request, $response) { $response->writeHead(200, array('Content-Type' => 'text/plain')); $query = $request->getQuery(); $data = isset($query["data"]) ? $query["data"] : ""; $response->end("www.{$data}\n"); }; $loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $http = new React\Http\Server($socket, $loop); $http->on('request', $app); $socket->listen($port, '0.0.0.0'); $loop->run(); ?>
把上面的代碼保持為文件reactphp.php。然后啟動服務:
php ./reactphp.php 5501
最后,我們驗證下效果,可以通過下面的方式訪問。
$curl http://10.101.80.141:5501/?data=bo56.com
www.bo56.com
ReactPHP也有自己的生態圈。如進行異步mysql查詢的react-php。
小結
ReactPHP作為Node.js的PHP版本。在實現思路,使用方法,應用場景上的確有很多相似之處。但是ReactPHP畢竟比Node.js年輕,目前生態圈還是不如Node.js完善。目前文檔也不是很完善,在國內應用也比較少。但是相信,它會越來越完善,應用越來越廣。(責編:張之穎)
作者簡介
信海龍,淘寶技術專家。2006年畢業於河北大學政法學院。之后,便踏上了互聯網開發的不歸路。目前已經有9年的互聯網開發經驗。2013年加入淘寶技術部,把工作中遇到的問題記錄到博客(www.bo56.com)。同時也是多個開源項目的開發者和維護者。