POSTS
Gearman 不一樣的用法~~
Gearman
你所知道的Gearman
可以導入大量數據、發送許多電子郵件、編碼視頻文件、挖據數據並構建一個中央日誌設施 — 所有這些均不會影響站點的體驗和響應性。可以並行地處理數據。而且,由於 Gearman 協議是獨立於語言和平台的,所以您可以在解決方案中混合編程語言。比如,可以用 PHP 編寫一個 producer,用 C、Ruby 或其他任何支持 Gearman 庫的語言編寫 worker。
你所應用Gearman[
]1
來自官網的範例:
Client:發送工作需求給Server
addServer();
echo "Sending job\n";
# Send reverse job
$result = $client->do("reverse", "Hello!");
if ($result)
echo "Success: $result\n";
Worker:接手處理Server工作
# Create our worker object.
$worker= new GearmanWorker();
# Add default server (localhost).
$worker->addServer();
# Register function "reverse" with the server.
$worker->addFunction("reverse", "reverse_fn");
while (1)
{
print "Waiting for job...\n";
$ret= $worker->work();
if ($worker->returnCode() != GEARMAN_SUCCESS)
break;
}
# A much simple reverse function
function reverse_fn($job)
{
$workload= $job->workload();
echo "Received job: " . $job->handle() . "\n";
echo "Workload: $workload\n";
$result= strrev($workload);
echo "Result: $result\n";
return $result;
}
實際上!!
所遇到狀況可能是…
- PHP Worker寫了一大堆.(發信一支,轉檔一支…)
- PHP Worker跑了一大堆.(沒事的時候SLEEP 100…..但是現在很忙阿!!馬上調整程式嗎?)
- PHP Worker跑了又沒做.(PHP開成常駐程式在跑.有很多狀況要處裡,很多狀況多到要ON CALL!!)
- 程式碼更新後又要重新開啟常駐程式.(一個就算啦.但是幾百個會怎樣?)
路不轉人轉!!
有沒有辦法克服上述問題?!
有~~
看一下系統架構:[
]2
說明:
一般來說,Client發送的是工作.
$result = $client->do("reverse", "Hello!");
這行看起來是要叫Worker處理reverse 這項工作 而工作內容為Hello!.
現在我們用.
$result = $client->do("Group1bgs", "php TestGearman.php D3 123231 adsadasdq");
你可以看到我改變了原本作法.
php TestGearman.php PARMS1 PARMS2 PARMS3 工作作內容變成這樣.
這時你一定有疑問??搞啥這樣Worker怎摸接?
以下是我啟動的Work的方式:
GetGearman.php 回傳我的Aplication設定值.
- Server:Jobs Server ip(可以連線多台SERVER)
- Localname:此範例Group1
- Threads:啟動幾個Worker
檔案:work.sh
#!/bin/bash
PWD=`eval pwd`
BASEDIR="${PWD}/$(dirname $0)"
export PATH=$PATH:/bin:/usr/bin:/usr/local/bin:${BASEDIR}
SERVER_HOT=`php ${BASEDIR}/GetGearman.php Server`
LOCAL_NAME=`php ${BASEDIR}/GetGearman.php Localname`
declare THREADS=`php ${BASEDIR}/GetGearman.php Threads`
LOG_DIR=`php ${BASEDIR}/GetGearman.php LOG_DIR`
WORK="${2}"
if [ "$WORK" = "" ]; then
WORK="bgs"
fi
__start( ){
declare a=0
while [[ $a -lt $THREADS ]]; do
(( a++ ))
PIDFILE="${LOG_DIR}/GearmanWork${WORK}${a}.pid"
PROMPT="-i ${PIDFILE} -h ${SERVER_HOT} -nw -f ${LOCAL_NAME}${WORK} xargs ${BASEDIR}/${WORK}.sh"
gearman ${PROMPT} &
done
}
__stop( ){
declare a=0
while [[ $a -lt $THREADS ]]; do
(( a++ ))
PIDFILE="${LOG_DIR}/GearmanWork${WORK}${a}.pid"
if [ ! -r $PIDFILE ] ; then
echo "warning, no pid${a} file found - gearman is not running ?"
exit 1
fi
kill -TERM `cat $PIDFILE`
rm -f $PIDFILE
done
}
__show_usage( ) {
echo "Usage: {start|stop|restart}"
exit 1
}
testing1=$(echo "${SERVER_HOT}" | grep "ERROR")
if [ "${testing1}" != "" ]; then
echo "${SERVER_HOT}"
exit 1
fi
testing2=$(echo "${LOCAL_NAME}" | grep "ERROR")
if [ "${testing2}" != "" ]; then
echo "${LOCAL_NAME}"
exit 1
fi
case "$1" in
start)
echo "Starting GearmanWork... ${WORK}"
__start
;;
stop)
echo "Stoping GearmanWork... ${WORK}"
__stop
;;
restart)
$0 stop ${WORK}
$0 start ${WORK}
;;
*)
__show_usage
;;
esac
使用方式:
$ ./work.sh start 啟動
$ ./work.sh stop 停止
運作:[
]3
檔案bgs.sh:
負責執行工作 直接跑命令 以php來說已經不是常駐狀態下運作.還有輸出log以便錯誤狀況查測.(如果你的程式有錯誤也可以看到輸出的錯誤訊息)
#!/bin/bash
RED=$'\e[1;31m'
GREEN=$'\e[1;32m'
YELLOW=$'\e[1;33m'
BLUE=$'\e[1;34m'
PURPLE=$'\e[1;35m'
CYAN=$'\e[1;36m'
WHITE=$'\e[1;37m'
GREY=$'\e[1;30m'
NOR=$'\e[m'
export PATH=$PATH:/bin:/usr/bin:/usr/local/bin:$(dirname $0)
PWD=`eval pwd`
BASEDIR="$(dirname $0)/../"
LOGDIR=$(php GetGearman.php LOG_DIR)
LOGFILE="${LOGDIR}/bgs.log"
time=$(date "+%Y/%m/%d %H:%M:%S")
time2=$(date "+%Y_%m_%d_%H_%M_%S")
logkey=${LOGDIR}/bgs/${time2}$(echo "${*}" | md5sum | cut -c 1-5).log
mkdir -p ${LOGDIR}/bgs
echo "$time $* ${logkey}" >> ${LOGFILE}
## cd ${BASEDIR}
echo "${YELLOW}*** ${RED}Running ${CYAN}${*} ${RED}...${NOR}" >> ${logkey}
(bash -c "${*}") | tee -a ${logkey} 2>&1
每次Worker執行的工作都是一次性的呼叫php,沒有常駐.
以我來說我的專案會以git做版本控管,在正式機器上會在crontab裡加入簡單的shell script每次更新 product的branch.
而我的Worker並不需要重起.因為每次都是獨立呼叫php,自然而然專案由git更新後執行的也是最新的程式碼.