Daemon process
场景:
监听 MySQL binlog 变更,将关注的事件发送到对应服务,代码逻辑中依赖 xlib、已有 handler
所以此常驻的服务也使用 handler 实现
1 handler
若非命令行请求此 handler,则直接返回 ERR
@funcattr.api
def event_send(req, log_file=None, log_pos=None):
"""
event send
"""
if req.wsgienv.get("REQUEST_METHOD", "UNKNOW") != "COMMAND":
req.error_str = "req method is not command"
return retstat.ERR
try:
_event_send(req, log_file=log_file, log_pos=log_pos)
except BaseException:
logger.error("action:event_send_except, version:{}, err_msg:{}".format(__version, traceback.format_exc()))
return retstat.OK
2 管理脚本
#!/bin/bash
CUR_DIR=$(cd `dirname $0`; pwd)
cd ${CUR_DIR}
EXEC="python2.7"
STDOUT="${CUR_DIR}/logs/__app_stdout"
APP_PATH=$1
APP_PATH="${APP_PATH%/}" # 移除结尾的斜杠
if awk -F'/' 'NF==3' <<< "$APP_PATH" && [[ "$APP_PATH" == /* ]]; then
: # 这是一个空操作,相当于什么都不做
else
# usage
echo -e "\nUsage: $0 APP {start|stop|restart|status}"
echo -e ${WITE}" APP start "${NC}"Start app processes."
echo -e ${WITE}" APP stop "${NC}"Kill all app processes."
echo -e ${WITE}" APP restart "${NC}"Kill all app processes and start again."
echo -e ${WITE}" APP status "${NC}"Show app processes status."
echo "app examples: /app_event/event_send"
exit 1
fi
STATUS_DIR_NAME_TMP="${APP_PATH#/}" # 移除开头的斜杠
STATUS_DIR_NAME="${STATUS_DIR_NAME_TMP//\//-}" # 将所有剩余的斜杠替换为短横线
DISP_NAME=$APP_PATH
PROC_SIG="95421699"
# Consts
RED='\033[1;91m'
GREN='\033[1;92m'
WITE='\033[1;97m'
NC='\033[0m'
# Global vailables
PROC_COUNT="0"
function count_proc()
{
PROC_COUNT=$(ps -ef | grep $APP_PATH | grep $PROC_SIG |grep -vc grep)
}
function list_proc()
{
ps -ef | grep -v grep | grep $PROC_SIG |grep --color $APP_PATH
}
function list_proc_pids()
{
ps -ef | grep $APP_PATH | grep $PROC_SIG | grep -v grep | awk '{print $2}'
}
function start_procs()
{
mkdir -p ./status/${STATUS_DIR_NAME}
printf "Starting $DISP_NAME processes"
count_proc
if [ $PROC_COUNT \> 0 ]; then
echo
list_proc
echo -e ${RED}"\n[ERROR]" ${NC}"Start $DISP_NAME failed, processes already runing."
exit 0
fi
date >> $STDOUT
supervise -p ${CUR_DIR}/status/${STATUS_DIR_NAME} -f "${EXEC} ${CUR_DIR}/test_handler.py ${APP_PATH} --PROC_SIG=${PROC_SIG}"
sleep 1
list_proc
count_proc
if [ $PROC_COUNT == 0 ]; then
echo -e ${RED}"\n[ERROR]" ${NC}"Start $DISP_NAME failed."
exit -1
fi
echo -e ${GREN}"\n[OK]" ${NC}"$DISP_NAME start succesfully."
}
function stop_procs()
{
printf "Stoping $DISP_NAME"
count_proc
if [ ${PROC_COUNT} -eq 0 ]; then
echo -e ${RED}"\n[ERROR]" ${NC}"$DISP_NAME process not found."
return
fi
# stop process
kill -15 $(list_proc_pids)
count_proc
check_count=0
while [ ${PROC_COUNT} -ne 0 ]; do
printf "."
sleep 0.2
count_proc
let check_count=$check_count+1
if [[ ${check_count} > 10 ]]
then
kill -9 $(list_proc_pids)
fi
done
echo -e ${GREN}"\n[OK]" ${NC}"$DISP_NAME stop succesfully."
}
function status_procs()
{
count_proc
echo -e ${RED}${PROC_COUNT}${NC} "$DISP_NAME processes runing."
}
MODE=${2}
case ${MODE} in
"start")
start_procs
;;
"stop")
stop_procs
;;
"restart")
stop_procs
start_procs
;;
"status")
status_procs
;;
*)
# usage
echo -e "\nUsage: $0 APP {start|stop|restart|status}"
echo -e ${WITE}" APP start "${NC}"Start app processes."
echo -e ${WITE}" APP stop "${NC}"Kill all app processes."
echo -e ${WITE}" APP restart "${NC}"Kill all app processes and start again."
echo -e ${WITE}" APP status "${NC}"Show app processes status."
exit 1
;;
esac
2.1 PROC_SIG
--PROC_SIG=95421699 仅作为进程标识使用,防止意外 kill 包含 "$APP_PATH" 字符串的其他进程
test_handler.py 会自动过滤非 handler 的参数
Last updated