一.概述
專案是棋牌,web架構是典型的lnmp,server產生的牌局通過http協議請求webserver,由php分析並持久化到mysql,中間參雜了很多業務邏輯,整個流程耗時平均接近2s。
這種方式存在以下2個問題
1.整個流程是同步的,server會一直等待php響應,一旦server處理不慎,會造成server阻塞,玩家無法玩牌。
2.如果牌局數量較多,會占用較多的php-fpm程序,可能造成php-fpm無法處理其他業務。
二.改進方式
後面改由server把牌局資料寫到redis佇列裡,php使用守護程序處理redis佇列。
cron每5分鐘執行gamelog.php,gamelog檢測牌局佇列數量,根據佇列的數量動態fork對應的子程序處理牌局業務,當子程序數量有多餘的空閒程序,gamelog.php
會殺掉多餘的程序,這種方式參考了php-fpm的dynamic模式,具體實現如下:
define('len', 50);//單程序處理牌局佇列長度
define('proc_min', 2);//
最小程序數
define('proc_max', 5);//
最大程序數
ini_set('memory_limit', '128m');
umask(002);
set_time_limit(0);//
cli模式非必須
$daemonnum = (int) `ps -ef | grep "gamelog.php" | grep -v grep | awk '$3 == 1 ' | wc -l`;//
當前守護程序數
$key = akey::gamelog();
);$wokernum = ceil($len / len);//
需要的程序數
($wokernum
< proc_min) && ($wokernum =proc_min);
if($daemonnum
< $wokernum)
exit
; }
else
if($pid > 0)
else
}}else
if($daemonnum > $wokernum)'`;
$apid = explode(php_eol, $pidstr
);
$wokernum = max($wokernum, proc_min);//
最少保留proc_min個守護程序
$killnum = $daemonnum - $wokernum
;
foreach($apid
as$pid
)
if(posix_kill($pid,sigkill))}}
}
php執行shell命令除了system(),exec(),還可以使用``。
posix_setsid()函式php手冊裡只有一句說明 make the current process a session leader
posix_setsid對應的unix系統函式是setsid(),當程序呼叫setsid會產生乙個新的會話,而且這個程序將不受終端控制
之前程序有終端控制也會被解除,所以我們在命令列啟動gamelog.php,然後關掉終端不會殺掉gamelog.php產生的子程序
三.改進後的效果
1.改進後server寫redis佇列遠比通過http協議請求php快,極大減少了server等待牌局處理的時間。
2.php-fpm不用處理牌局的請求,改由後台程序處理,釋放了php-fpm。
php守護程序
class daemon 啟動程序 return bool public function main this logmessage running.this isrunning true while this isrunning return true 停止程序 return void publi...
PHP守護程序
php也是可以直接進行守護程序的啟動與終止的,相對於shell來說會簡單很多,理解更方便,當然了php的守護程序要實現自動重啟還是要依賴於shell的crontab日程表,每隔一段時間去執行一次指令碼看指令碼是否需要重啟,如果需要則殺掉程序刪除runfile檔案,重新啟動並在runfile檔案中寫入...
使用PHP做Linux Unix守護程序
起源 linux unix 下守護程序 daemon 大家都知道,比如我們常用的httpd mysqld等等,就是常駐記憶體執行的程式,類似於windows下的服務。一般守護 程序都是使用c c 來寫,就是通過fork生成子程序,當前臺shell下的父程序被殺掉,子程序就轉到後台執行,為了不在終端產...