gunicornãsupervisorã§å¶å¾¡ãã¤ã¤hot deployã§ããããã«ãã
ã¿ã¤ãã«ã®éããgunicornãªWebã¢ããªãsupervisorã§å¶å¾¡ãã¤ã¤hot deployã§ããããã«ããã¡ã¢ã§ãã
ç»å ´äººç©
- supervisor v3.3.1
- gunicorn v19.9.0
- start_server v0.34
- unicornherder v0.1.0
- envdir v0.7 ã® standaloneç
- ã¡ãªã¿ã« checkinstall ã§éã«debå
åé¡
- gunicornã®hot deployãå©ç¨ããå ´åãç´æ¥ã¯supervisorã®å¶å¾¡ä¸ã«ç½®ããªã
- gunicornã¯hot deployã®ä»çµã¿ãæã£ã¦ãã
- æµã
- gunicornã®masterããã»ã¹ã«USR2ã·ã°ãã«ãéãã¨ãæ°ããmasterããã»ã¹ãç£ã
- ã¤ã¾ãæ°masterã®è¦ªããã»ã¹ã¯æ§master
- æ§masterã¨æ§workerã¯çãç¶ãã¦ããã®ã§ãã»ã©ããé åãã§æ§masterã«QUITã·ã°ãã«ãªã©ãéã£ã¦æ»ãã§ããã
- æ°masterã®è¦ªãæ»ãã ã®ã§ãinit (PID 1) ãæ°masterã®è¦ªã¨ãªã
- gunicornã®masterããã»ã¹ã«USR2ã·ã°ãã«ãéãã¨ãæ°ããmasterããã»ã¹ãç£ã
- ã¨ããããã§ãsupervisorè¦ç¹ã ã¨gunicornï¼æ§masterï¼ãæ»ãã ã®ã§ã¾ãç«ã¡ä¸ãããã¨ããããæ°masterã¯initã親ã¨ãã¦èµ·åãã¦ããã®ã§ç«¶åãã¡ããæ¬¡ç¬¬
çµè«
- supervisor + unicornherder + gunicorn
æ¡1: start_serveré ä¸ã§gunicornãç«ã¡ãããhot deployã¯start_serverã®æ©è½ã使ã
## /etc/supervisor/conf.d/oreno.conf [program:oreno] command=/home/hirose31/oreno/script/start directory=/home/hirose31/oreno ...
## /home/hirose31/oreno/script/start
#!/bin/bash
export PYENV_ROOT="/home/hirose31/oreno/pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
exec start_server \
--port 127.0.0.1:1919 \
--signal-on-term=TERM \
--signal-on-hup=QUIT \
--kill-old-delay=10 \
-- \
/home/hirose31/oreno/script/start-gunicorn
## /home/hirose31/oreno/script/start-gunicorn
#!/bin/bash
if [[ -n "$SERVER_STARTER_PORT" ]]; then
GUNICORN_FD=
for l in $(echo $SERVER_STARTER_PORT | tr ';' ' '); do
GUNICORN_FD="$GUNICORN_FD $(echo $l | cut -d= -f2)"
done
export GUNICORN_FD=$(echo $GUNICORN_FD | tr ' ' ',')
fi
exec /usr/local/bin/envdir /home/hirose31/oreno/env \
gunicorn -w 3 --reuse-port --capture-output oreno:application
ããã§ supervisorctl signal HUP oreno ã§ start_server ã« HUP ãéãã¨ãstart_serverãæ°ãã«gunicornãèµ·åãã¦ã10ç§å¾ã«å¤ãgunicornã«QUITãéã£ã¦æ®ºãã¦ããããã¯ãã
ã¤ã¾ããï¼gunicornã®æ©è½ã§ã¯ãªãï¼start_serverã®æ©è½ã§hot deployãå®ç¾ã§ãããã¯ãã
start_server ã«å¯¾å¿ããã«ã¯ããã¤ãã®è¦ä»¶ãå¿ è¦ã§ããã
- Server::Starterã«å¯¾å¿ããã¨ã¯ã©ããããã¨ã - limitususâs diary
- ãServer::Starterã«å¯¾å¿ããã¨ã¯ã©ããããã¨ããã®è£è¶³ - sonots:blog
- Server::Starter ã§ Unicorn ãèµ·åããå ´åã® Slow Restart - sonots:blog
Unicornã® UNICORN_FD ã¨åæ§ã®ãã®ã gunicorn ã«ã¯ GUNICORN_FD ã¨ããç°å¢å¤æ°åã§åå¨ããã®ã§ãgunicornãstart_serverã«å¯¾å¿ã§ãããã¯ãã
ãããã¯ãããªã®ã§ãã£ãï¼
gunicornã® ãã®pull request ã§ãGUNICORN_FD ãè©ä¾¡ããã¨ããã®ããã®ãããªæ¡ä»¶ä»ãã«ãªãã
### gunicorn/arbiter.py: start
elif self.master_pid:
fds = []
for fd in os.environ.pop('GUNICORN_FD').split(','):
fds.append(int(fd))
åã£ç«¯ã®èµ·åæã¯ master_pid 㯠0 ãªã®ã§ GUNICORN_FD ã¯è©ä¾¡ãããªãã®ã§ãã£ãï¼ï¼
æ¡ä»¶ã elif os.environ.get('GUNICORN_FD', ''): ã«ããã°æå¾
éãåããã¨ã¯ç¢ºèªã§ãããã ãã©ãã§ããã°gunicornã«æãå
¥ããªãã§ä½¿ãããã®ã§ãã®æ¡ã¯ã¨ããããããã«â¦
å°æ¥ãå¤é¨ç±æ¥ã® GUNICORN_FD ãè©ä¾¡ããããã«ãªã£ãããgunicornã¯--configãªãã·ã§ã³ã§pythonã®ææ³ã§è¨å®ãæ¸ããããã¡ã¤ã«ãæå®ãããã¨ãã§ããã®ã§ãããã§ SERVER_STARTER_PORT ãåç
§ã㦠GUNICORN_FD ãã»ããããå¦çãæ¸ããããpre_fork, post_fork hookã使ã£ã¦ãServer::Starter ã§ Unicorn ãèµ·åããå ´åã® Slow Restart - sonots:blog ã¨åããã¨ãå®ç¾ã§ããããããªããã¨æãã¾ãã
ä½è«ã§ãããstart_server ã® server-prog ã®æå®ã¯ãã©ããããã¹ã¯ãªããã®ã¿ããªãã·ã§ã³æå®ç¡ãã«ããã®ããå§ããã¾ãã
ä¾ãã° start_server -- /my/app -p 8 ã§èµ·åãã¦ã㦠-p 16 ã«å¤ãããã¨ãã¯ãstart_server èªä½ã®åèµ·åãå¿
è¦ï¼ã¤ã¾ãhot deployã§ããªãï¼ã«ãªã£ã¦ãã¾ãã¾ãããããã©ãããã¦ã㦠start_server -- /my/app_wrapper ã§èµ·åãã¦ããå ´åã¯ãapp_wrapper ã®ä¸ãæ¸ãæã㦠start_server ã« HUP ãéãã°OKã«ãªãã¾ãã
start_server -- envdir ./env sh -c 'exec /my/app -p ${MAX_PROCESS:-8}' ã¨æ¸ãã°HUPã§å¼æ°ã®å¤ãï¼envdirçµç±ã§ï¼å¤ãããã¨ã¯å¯è½ã§ãããããæå·§çã ããªãã·ã§ã³ã®ç¨®é¡ã®å¢æ¸ã«ã¯å¯¾å¿ã§ããªãã®ã§ãç´ ç´ã«ã©ããã¼ã¹ã¯ãªãããç¨æããæ¹ãããã§ãããã
æ¡2: unicornherderé ä¸ã§gunicornãç«ã¡ãããhot deployã¯gunicornã®æ©è½ã使ã
ãgunicorn supervisorãã§ã°ã°ãã¨ã¿ãªãããå°ãã®ããã§ã対å¿ã¨ã㦠rainbow-saddle 㨠unicornherder ãããæãããã¦ãã¾ãã
rainbow-saddleã¯ãcannot actively maintain itãã ãããªã®ã§ãunicornherderã試ãã¦ã¿ã¾ãã
## /etc/supervisor/conf.d/oreno.conf [program:oreno] command=/home/hirose31/oreno/script/start directory=/home/hirose31/oreno ...
## /home/hirose31/oreno/script/start
#!/bin/bash
export PYENV_ROOT="/home/hirose31/oreno/pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
exec unicornherder -o 10 -p /var/run/oreno.pid -- \
-w 3 --reuse-port --capture-output oreno:application
unicornherderã®æµãã¯ãããªæãã§ãã
- gunicornã
--pid FILE --daemonã¤ãã§èµ·åãã- masterã®PIDã¯æå®ã®ãã¡ã¤ã«ã«æ¸ãåºããã
- unicornherderã®
--pidfile PATHã§PIDãã¡ã¤ã«ãæå®ããªãã¨ãcwdã«PIDãã¡ã¤ã«ãä½ãããã®ã§æ³¨æ
- unicornherderã®
- gunicornã¯unicornherderã®å ãé¢ããinitã®åããã»ã¹ã¨ãªã
- masterã®PIDã¯æå®ã®ãã¡ã¤ã«ã«æ¸ãåºããã
- unicornherderã¯HUPãåããã¨ãgunicornã®masterã«USR2ãéã
- gunicornã®hot deployãéå§ãããæ°masterãèªçãã
- gunicornã«ãã£ã¦PIDãã¡ã¤ã«ãæ´æ°ããã
- unicornherderã¯PIDãã¡ã¤ã«ã2ç§ééã§ãã¼ãªã³ã°ãã¦ãmasterã®å¤åãæ¤ç¥ãã
- masterã®å¤åãæ¤ç¥ããã¨ã
- overlap (ããã©ã«ã120ç§) ã®æéã ãsleepãã
- ãã®éã¯æ°æ§workerãæ··å¨ãã
- å¾ãæ§masterãæ®ºã
- masterã«WINCH, QUITã·ã°ãã«ãéã
- QUITãåããworkerã¯å¦çä¸ã§ãã£ã¦ãå³ãæ»ã¬
- overlap (ããã©ã«ã120ç§) ã®æéã ãsleepãã
unicornherderã¯gunicornãåããã»ã¹ã¨ãã¦ããããgunicornã¯initã®åããã»ã¹ã¨ãªãç¹ã«æåããªãï¼ãã£ã¨æãã¾ããããããã¯å¤ãè¯ãdaemonãããã§ãããã¾ãéåæã¯ãªãã§ãã
ããã§ä¸å¿ãåé¡ã¯è§£æ±ºã§ãããã§ãããunicornherderã¯gunicornã³ãã³ãã§ã®gunicornã®èµ·åãããµãã¼ããã¦ãã¾ããã
gunicornã®èµ·åæ¹æ³ãPythonã®å種WAFã¨ã®é£æºæ¹æ³ã¯ gunicornã³ãã³ã以å¤ã«ãããã¾ããä¾ãã°ãBottle ã 㨠bottle.run() ã« server='gunicorn' ãä¸ããã¨ãgunicornãèµ·åãã¾ãã
ãã®å ´åã¯ãunicornherderã¯--gunicorn-bin, -gãªãã·ã§ã³ã§gunicornã®ãã«ãã¹ãæå®ã§ããã®ã§ããã使ãã¾ãã
## /home/hirose31/oreno/script/start
#!/bin/bash
export PYENV_ROOT="/home/hirose31/oreno/pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
exec unicornherder -o 10 -p /var/run/oreno.pid \
-g /home/hirose31/oreno/script/oreno-gunicorn \
--
oreno-gunicorn ã¯ã好ã¿ã®æ¹æ³ã§gunicornãªããã»ã¹ãç«ã¡ä¸ããå¦çãæ¸ããã¹ã¯ãªããã§ãã
## /home/hirose31/oreno/script/oreno-gunicorn #!/bin/bash exec /home/hirose31/oreno/bin/oreno-python /home/hirose31/oreno/omaeno.py
注æç¹ã¯ä»¥ä¸ã®éãã§ãã
- unicornherderã®
-pãªãã·ã§ã³ã§æå®ããPIDãã¡ã¤ã«ã¨ãgunicornãæ¸ãåºãPIDãã¡ã¤ã«ãä¸è´ããã - gunicornã¯daemonã¢ã¼ãã§èµ·åããããã«ãã
ãããã«
unicornherderã使ãã°ç®çãéæã§ãããã¨ããããã¾ããããå人çã«å®å¿ã¨ä¿¡é ¼ã¨å®ç¸¾ã®ãã start_server ã使ããã仿¥ãã®é ã§ãã