如何在启动时可靠地启动多个DJango FCGI服务器?

时间:2012-03-05 07:32:44

标签: django linux bash ubuntu

我目前使用以下脚本启动我的DJango FCGI服务器:

#!/bin/bash
MYAPP=$1
PIDFILE=/var/run/${MYAPP}_fcgi.pid
SOCKET=/var/django/${MYAPP}/socket.sock
MANAGESCRIPT=/var/django/${MYAPP}/manage.py
# Maximum requests for a child to service before expiring
#MAXREQ=
# Spawning method - prefork or threaded
#METHOD=
# Maximum number of children to have idle
MAXSPARE=2
# Minimum number of children to have idle
MINSPARE=1
# Maximum number of children to spawn
MAXCHILDREN=3

cd "`dirname $0`"

function failure () {
  STATUS=$?;
  echo; echo "Failed $1 (exit code ${STATUS}).";
  exit ${STATUS};
}

function start_server () {
  $MANAGESCRIPT runfcgi socket=$SOCKET pidfile=$PIDFILE \
    ${MAXREQ:+maxrequests=$MAXREQ} \
    ${METHOD:+method=$METHOD} \
    ${MAXSPARE:+maxspare=$MAXSPARE} \
    ${MINSPARE:+minspare=$MINSPARE} \
    ${MAXCHILDREN:+maxchildren=$MAXCHILDREN} \
    ${DAEMONISE:+damonize=True}
  touch $SOCKET
  chown www-data:www-data $SOCKET
  chmod 755 $SOCKET
}

function stop_server () {
  if [ -f "$PIDFILE" ]
  then
    kill `cat $PIDFILE` || failure "Server was not running."
    rm $PIDFILE
  fi
}

DAEMONISE=$3

case "$2" in
  start)
    echo -n "Starting fcgi: "
    [ -e $PIDFILE ] && { echo "PID file exsts."; exit; }
    start_server || failure "starting fcgi"
    echo "Done."
    ;;
  stop)
    echo -n "Stopping fcgi: "
    [ -e $PIDFILE ] || { echo "No PID file found."; exit; }
    stop_server
    echo "Done."
    ;;
  restart)
    echo -n "Restarting fcgi: "
    [ -e $PIDFILE ] || { echo -n "No PID file found..."; }
    stop_server
    start_server || failure "restarting fcgi"
    echo "Done."
    ;;
  *)
    echo "Usage: $0 {start|stop|restart} [--daemonise]"
    ;;
esac

exit 0

我手动调用这个:

/var/django/server.sh mysite start

这很好但是当我的托管公司重新启动我们的服务器时,它留下了两个问题:

  1. 我没有自动启动多个网站的方式。
  2. 我最终得到了一个mysite_fcgi.pid文件但没有关联的进程。
  3. 所以我有两个问题:

    1. 如何在启动时自动启动网站列表(存储在纯文本文件中)?即拨打/var/django/server.sh mysite1 start然后/var/django/server.sh myothersite start
    2. 如果进程不存在并且尝试正常启动服务器,如何删除.pid文件?

2 个答案:

答案 0 :(得分:1)

  1. 创建一个init脚本并将其分配给相应的运行级别。
  2. 您需要在启动/初始化脚本(您将在步骤1中编写)中实现此功能
  3. 或者,使用像supervisord这样的流程管理器来处理您的所有问题。

    以下是来自supervisord的fcgi的配置示例。

    [fcgi-program:fcgiprogramname]
    command=/usr/bin/example.fcgi
    socket=unix:///var/run/supervisor/%(program_name)s.sock
    process_name=%(program_name)s_%(process_num)02d
    numprocs=5
    priority=999
    autostart=true
    autorestart=unexpected
    startsecs=1
    startretries=3
    exitcodes=0,2
    stopsignal=QUIT
    stopwaitsecs=10
    user=chrism
    redirect_stderr=true
    stdout_logfile=/a/path
    stdout_logfile_maxbytes=1MB
    stdout_logfile_backups=10
    stderr_logfile=/a/path
    stderr_logfile_maxbytes=1MB
    stderr_logfile_backups
    environment=A=1,B=2
    

答案 1 :(得分:1)

如何在启动时自动启动站点列表(存储在纯文本文件中)?

通常,您的操作系统提供了一个文件,您可以在启动时挂钩命令。例如,arch linux uses rc.localgentoo either /etc/local.start either /etc/local.d/*.startdebian requires you to make an init script - 这基本上是一个以“start”或“stop”作为参数并位于/etc/init.d或/ etc /中的脚本rc.d取决于分布...

您可以使用一些bash代码。

for site in $(</path/to/text/file); do
    /var/django/server.sh $site start
done

如果进程不存在并且尝试正常启动服务器,我如何摆脱.pid文件?

if [[ -f $PIDFILE ]]; then # if pidfile exists
    if [[ ! -d /proc/$(<$PIDFILE)/ ]]; then # if it contains a non running proc
        unlink $PIDFILE # delete the pidfile
    fi
fi