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