服務(wù)器端PHP多進(jìn)程編程實(shí)戰(zhàn)
最近比較PHP跟Python, Erlang的特性,發(fā)現(xiàn)PHP有很多人們不常用到的特性。用PHP CLI可以實(shí)現(xiàn)很多不錯(cuò)的應(yīng)用。比如做搜索引擎的爬蟲, 長期運(yùn)行的計(jì)算腳本, 完全可以取代其他語言來做服務(wù)器的運(yùn)維。這對(duì)于熟悉PHP的人來說如虎添翼。
51CTO推薦閱讀:讓PHP開發(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解決了多大部分線程通信問題。所以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)頁的請(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開發(fā)語言,所以用PHP來做服務(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)程的同步問題,不用考慮數(shù)據(jù)的共享問題。PHP CLI(SAPI SERVER API) 命令行接口可以用來做CRON計(jì)劃任務(wù), 圖形界面程序 (使用GTK庫)。
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)行。開始時(shí)創(chuàng)建一個(gè)鎖文件, 結(jié)束時(shí)刪除。或者用ps命令來處理。任務(wù)隊(duì)列可以用MySQL來實(shí)現(xiàn),或者Key/VALUE數(shù)據(jù)庫,或者消息隊(duì)列來實(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寫成文件。
◆定時(shí)檢查PID文件是否存在 檢查ps -o pid=或者file_exists(‘/proc/’)。
◆如果線程不存在重啟進(jìn)程。
回顧以前用Java或者Python做的服務(wù)器端的服務(wù)都可以用PHP來實(shí)現(xiàn)。單一語言更容易維護(hù)。以往人們對(duì)于Web語言的認(rèn)識(shí)很片面,例如多線程、事 務(wù)這些東西都可以改變方式來達(dá)到同樣的目的。
原文鏈接:http://blog.eood.cn/server-side-php-progress-program-best-practice
【編輯推薦】