服務(wù)器端PHP多進(jìn)程編程實(shí)戰(zhàn)
最近比較PHP跟Python, Erlang的特性,發(fā)現(xiàn)PHP有很多人們不常用到的特性。用PHP CLI可以實(shí)現(xiàn)很多不錯(cuò)的應(yīng)用。比如做搜索引擎的爬蟲(chóng), 長(zhǎng)期運(yùn)行的計(jì)算腳本, 完全可以取代其他語(yǔ)言來(lái)做服務(wù)器的運(yùn)維。這對(duì)于熟悉PHP的人來(lái)說(shuō)如虎添翼。
51CTO推薦閱讀:讓PHP開(kāi)發(fā)者事半功倍的十大技巧
為什么PHP多進(jìn)程很好? 網(wǎng)游服務(wù)器大部分都使用多線程而不是多進(jìn)程的原因也在于進(jìn)程比線程更加穩(wěn)定。而且多線程適合現(xiàn)在多核服務(wù)器的應(yīng)用場(chǎng)景,更能發(fā)揮多核運(yùn)算的能力。進(jìn)程的維護(hù)可以用很多操作系統(tǒng)級(jí)別的工具。Message Queue解決了多大部分線程通信問(wèn)題。所以PHP多進(jìn)程很適合做服務(wù)器端的計(jì)算密集型的應(yīng)用。
據(jù)一家越南IT公司介紹,他們成功的把PHP后臺(tái)多進(jìn)程用在法律文件的分發(fā)、處理銀行賬戶的金額這樣的企業(yè)級(jí)的應(yīng)用上。
使用后臺(tái)PHP進(jìn)程可以不影響服務(wù)器同時(shí)處理網(wǎng)頁(yè)的請(qǐng)求。這種后臺(tái)進(jìn)程一旦發(fā)生失敗很容易查處原因進(jìn)行恢復(fù)或者補(bǔ)救,所以健壯性更高。不同的進(jìn)程相互隔離,更加高效,可以統(tǒng)一調(diào)度各個(gè)服務(wù)進(jìn)程。
PHP是目前應(yīng)用最廣泛的Web開(kāi)發(fā)語(yǔ)言,所以用PHP來(lái)做服務(wù)器端的應(yīng)用可以降低成本??梢杂矛F(xiàn)有人員、現(xiàn)有配置、甚至做到代碼重用。什么樣的場(chǎng)景更適合用PHP后臺(tái)多進(jìn)程呢?比如郵件的分發(fā)、遠(yuǎn)程服務(wù)的調(diào)用、數(shù)據(jù)的聚合、計(jì)劃任務(wù)、計(jì)算結(jié)果的緩存這些不需要立即返回的地方。
PHP單進(jìn)程在某些地方完全可以達(dá)到目的,而且更加容易實(shí)現(xiàn),不用考慮進(jìn)程的同步問(wèn)題,不用考慮數(shù)據(jù)的共享問(wèn)題。PHP CLI(SAPI SERVER API) 命令行接口可以用來(lái)做CRON計(jì)劃任務(wù), 圖形界面程序 (使用GTK庫(kù))。
PHP CLI例子
- php -f test.php
 - php -r “echo time();”
 - php -R as python style
 
PHP讀取命令行參數(shù):
- <?php
 - #!/usr/bin/php -q
 - echo “Test Arguments:\n”;
 - echo $_SERVER["argc"].”\n”;
 - echo $_SERVER["argv"][0].”\n”;
 - ?>
 
PHP命令行接口標(biāo)準(zhǔn)輸入輸出:
- <?php
 - #!/usr/bin/php -q
 - /* Define STDIN in case if it is not already defined by PHP for some reason */
 - if(!defined(“STDIN”)) {
 - define(“STDIN”, fopen(‘php://stdin’,'r’))
 - }
 - echo “Hello! What is your name (enter below):\n”;
 - $strName = fread(STDIN, 80); // Read up to 80 characters or a newline
 - echo ‘Hello ‘ , $strName , “\n”;
 - ?>
 
CRONJOB可以定時(shí)運(yùn)行某些任務(wù),但要防止重復(fù)運(yùn)行。開(kāi)始時(shí)創(chuàng)建一個(gè)鎖文件, 結(jié)束時(shí)刪除。或者用ps命令來(lái)處理。任務(wù)隊(duì)列可以用MySQL來(lái)實(shí)現(xiàn),或者Key/VALUE數(shù)據(jù)庫(kù),或者消息隊(duì)列來(lái)實(shí)現(xiàn)。
進(jìn)程控制相關(guān)函數(shù):
- Process Control Extensions
 - pcntl_fork()
 - posix_setsid()
 - posix_kill
 - pcntl_wait
 - pcntl_signal
 - SIGHUP
 - SIGTERM; system shutdown, kill
 - SIGINT; sent by Ctrl+c
 - SIGKILL (uncatchable); unresponsive, kill -9
 - SIGCHLD; child status change
 - SIGSTP; sent by Ctrl+z
 - SIGCONT; resume from stop, fg
 
PHP不能對(duì)某些錯(cuò)誤拋出異常,如何提高PHP多進(jìn)程應(yīng)用的容錯(cuò)性?
◆可以監(jiān)控進(jìn)程,依賴進(jìn)程失敗后報(bào)告。
◆用CRONJOB實(shí)現(xiàn)監(jiān)控進(jìn)程。
◆將被監(jiān)控進(jìn)程PID寫(xiě)成文件。
◆定時(shí)檢查PID文件是否存在 檢查ps -o pid=或者file_exists(‘/proc/’)。
◆如果線程不存在重啟進(jìn)程。
回顧以前用Java或者Python做的服務(wù)器端的服務(wù)都可以用PHP來(lái)實(shí)現(xiàn)。單一語(yǔ)言更容易維護(hù)。以往人們對(duì)于Web語(yǔ)言的認(rèn)識(shí)很片面,例如多線程、事 務(wù)這些東西都可以改變方式來(lái)達(dá)到同樣的目的。
原文鏈接:http://blog.eood.cn/server-side-php-progress-program-best-practice
【編輯推薦】















 
 
 




 
 
 
 