Server::Starterã«å¯¾å¿ããã¨ã¯ã©ããããã¨ã
StarletãStarmanã¨çµã¿åããã¦ãã使ããã¦ããServer::Starterã§ãããæ®æ®µæ°ã«ããªããããªé¨åãèªãæ©ä¼ããã£ãã®ã§ã¡ã¢ã
Server::Starter㯠--port (TCP) ã --path (Unix Domain Socket) ã渡ãã¨ããã§listen(2)ãã¦èµ·åããworkerã«å¼ã渡ãã¦ãããã
ããã¯fork(2)ã¨exec(2)ã«ãã£ã¦ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãå¼ãç¶ããã¨ã«ããå®ç¾ããã¦ãããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãã®ãã®ãã©ã®ããã«å¼ã渡ãã¦ããã®ããã¨ããåé¡ã
exec(2)ã«ããå®è¡ãã¤ããªã¯å·®ãæãã£ã¦ãã¾ãã®ã§ãããã°ã©ã ä¸ã®å¤æ°ã«ããå¼ãç¶ããã¨ã¯ã§ããªãã
Server::Starterã§ã¯ãããç°å¢å¤æ°SERVER_STARTER_PORTã«ããå®ç¾ãã¦ããã
ãããã以ä¸ã®ãããªæãã
FD = integer EQ = '=' SEMICOLON = ';' SERVER_STARTER_PORT = PORT_DESCRIPTION ( SEMICOLON SERVER_STARTER_PORT ) PORT_DESCRIPTION = PORT_NAME EQ FD PORT_NAME = character+
PORT_NAMEã¯ã½ã±ããã®ç¨®é¡ã«ãã£ã¦éã£ã¦ãTCPã§ããã°ãã¼ãçªå·(8080)ã¨ããã¹ãå:ãã¼ãçªå·(localhost:8080)ãUnix Domain Socketã§ããã°ãã®ãã¹(/path/to/app.sock)ã¨ãªãã
PODã«ãæ¸ãã¦ããServer::Starter::server_portsã¯ãã®ç°å¢å¤æ°ãã»ã©ãã¦Perlã®ããã·ã¥ã«ãã¦è¿ãã¦ãããå°ããªãµãã«ã¼ãã³ã¨ãã¦å®è£
ããã¦ããã®ã§ãworkerãPerlã§ããã°ããã使ãã°ããã
workerã¯ç°å¢å¤æ°ããåãåã£ããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã®çªå·ãfdopen(3)ãã¦ï¼ãããã¯ãããããããã«)ãã®ã½ã±ãããå©ç¨ãããã¨ãã§ããã
ã¨ããã§å¥ã«workerãPerlã§ãããã¨ã¯è¦è«ããã¦ããªãã
Rubyã«unicornã¨ãããã¬ã¼ã ã¯ã¼ã¯ãããã
ãã¾ã詳ããã¯ç¥ããªãããWebãµã¼ãã¨ãã¦åä½ãããã®ã«ç¨ãããã¨ãã§ãããããã
ã¡ãã£ã¨ã½ã¼ã¹ãèªãã§ã¿ãã¨ãããç¡åæ¢graceful restartã®ä»çµã¿ã¨ãã¦ã
- fork(2)ãã
- åããã»ã¹ã¯èªåèªèº«ã«exec(2)ããå¾ã親ããã»ã¹ãããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãå¼ãç¶ãã§accept(2)ã§ããããã«ãã
- åããã»ã¹ã親ããã»ã¹ã«(èªèº«ãç¡äºèµ·åã§ãããã¨ãéç¥ããæå³ã§)ã·ã°ãã«ãéä¿¡
- 親ããã»ã¹ãçµäºãã
ã¨ãã£ãããã»ã¹ãçµã¦ãããã¨ãããã£ã(SIGUSR2ãéã£ãã¨ãã®æå)ã
ãã®ã¨ããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã®å¼ãç¶ãã«UNICORN_FDã¨ããç°å¢å¤æ°ãç¨ãã¦ããã©ã¼ãããã¯ç°ãªããã®ã®Server::Starterã¨åããããªãã¨ãè¡ã£ã¦ããã
unicornãdaemontoolsã®é
ä¸ã§åãããã¨æã£ãã¨ããmasterãgraceful restartãããã¨SIGUSR2ãéä¿¡ããã¨ã親ããã»ã¹ï¼æ§workerï¼ãçµäºããæç¹ã§åããã»ã¹ï¼æ°workerï¼ãinitããã»ã¹ã®é¤åã«å
¥ã£ã¦ãã¾ãã
ããããã¨daemontoolsã®ç®¡çããå¤ãã¦ãã¾ããã¨ãããdaemontools対å¿ã諦ãã¦ããçµç·¯ãããããã ãUnicorn general mailing list ()
foremanã¨ããã®ã使ãæããããããï¼ããã¯å
¨ç¶ç¥ããªãï¼最近のRubyなWebアプリの構成 | monoの開発ブログ
daemontools + Server::Starter ã¨ããã®ã¯æ§ã
ãªã¨ããã§ä½¿ããã¦ãããå®å¿ãã¦ä½¿ããã¨ããã®ããã£ã¦ããã®ä»çµã¿ã«unicornãè¼ãããã¨ãèãã¦ã¿ãã
unicornã®ããããã®ãã¸ãã¯ã¨ãã¦ã
- ENV['UNICORN_FD'] ã®åå¨ããã§ãã¯
- ãªããã°ããã§bind&listenãããã°fdopen(3)ç¸å½ãã¦ãæ§masterããã»ã¹ã«ã·ã°ãã«éä¿¡
- ãµã¼ãã¨ãã¦åã
ã¨ãªã£ã¦ãããããENV['SERVER_STARTER_PORT']ãENV['UNICORN_FD']ã«å¤æãã¦unicornãèµ·åãã¦ããã¨Server::Starterããèµ·åãããã¨ãã§ãã¦ãã¾ãã
å¤æã³ã¼ãã¯unicorn.rbèªèº«ã«æ¸ãã¦ãã¾ã£ã¦ãããããã¢ããªå
ã§hookã¨ãã¦æ¸ããã¨ãã§ããã
Server::StarterãSIGHUPãåãåã£ãã¨ãã¯æ§masterã«ã¯SIGTERMãéã£ã¦ãã¾ã£ã¦æ§ããªã(--signal-on-hup=TERM)ã
ãããã¦ããã¨ãunicornã¢ããªã®åèµ·åã§ã¯SIGUSR2ãdaemontoolsã®ã¢ããªã§ã¯svc -h(SIGHUP)ã¨ããæ··å¨éç¨ããéãããã¨ãã§ããã
å¤æã¯å¤§ä½ä»¥ä¸ã®ããã«ããã°ããã
# ãããªé¢¨ã«Server::Starterããç°å¢å¤æ°ã渡ã£ã¦ãã ENV['SERVER_STARTER_PORT'] = '80=3;443=4' # 以ä¸ã®ããã«ç°å¢å¤æ°ãå¤æãã ENV['UNICORN_FD'] = ENV['SERVER_STARTER_PORT'].split(';').map { |s| pf = s.split('=') pf[1] }.join(',') p ENV['SERVER_STARTER_PORT'] # ==> "80=3;443=4" p ENV['UNICORN_FD'] # ==> "3,4"
ã¨ãããã·ã³ãã«ã ãã©Perlã¨Rubyãèåããã話ã