ãã®è¨äºã¯ãnginx Advent Calendar 2022ãã®6æ¥ç®ã®è¨äºã§ãï¼
nginxã®ã¢ã¼ããã¯ãã£ã¯è¦ªããã»ã¹+åããã»ã¹ã®ã¢ã¼ããã¯ãã£ã§åããã»ã¹(以ä¸ã¯ã¼ã«ããã»ã¹)ãã¯ã©ã¤ã¢ã³ãã¨ã®ããåããè¡ã£ã¦ãã¾ãã
åæåå¦ç
- 親ããã»ã¹ãèµ·åãã
- socketãä½æãconfã«æ¸ããã¦ããå 容ã«ãªãããã«setsockopt(2)ãå®è¡ãã¦ãã
- ã¯ã¼ã«ã¼ããã»ã¹ãçæãã
ã¨ããæµãã§å®è¡ãã¦ããã¾ãããã®å¾ã¯ã¤ãã³ãé§åã¨ã³ã¸ã³ã§ã¤ãã³ãã®çºçã®ãã³ã«ã³ã¼ã«ããã¯ãå¼ã³åºãã¦ããå¦çã¨ãªã£ã¦ãã¾ããä»åã¯epollã§ã®å ´åãè¦ã¦ããã¾ãã
accept(2)ã®thundering herdåé¡
大æã®ã«ã¼ãã«ã¯accept(2)ãè¤æ°ããã»ã¹ããå¼ã³åºãã¨ãã¹ã¦ã®å¯ã¦ããããã»ã¹ãèµ·ããã¨ããå¦çã«ãªã£ã¦ãã¾ããããã®åé¡ã¯ç¾å¨ã¯è§£æ¶ããã¦ãã¾ãã
ãããããã¯accept(2)ãè¤æ°ããã»ã¹ãããããã¯ãã¦ããå ´åã«ãªãã¾ããepoll->acceptã®ãããªå ´åã«ã¯ä»ãå¤ãããepollã¯ãã¹ã¦ã®ããã»ã¹ãèµ·ããã®ã§å ¨ããã»ã¹ã§acceptãå®è¡ãEAGAINã帰ã£ã¦ããã¨ããå¦çãèµ°ã£ã¦ãã¾ãã¾ãããããã¯ã³ã³ããã¹ãã¹ã¤ãããçºçããã®ã§ä½è¨ãªå¦çã§ãããã¨ã¯å¤ããã¾ããã
void ngx_event_accept(ngx_event_t *ev) { s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK); if (s == (ngx_socket_t) -1) { err = ngx_socket_errno; if (err == NGX_EAGAIN) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err, // ã»ãããã»ã¹ããã§ã«accept(2)æ¸ã¿ãªãEAGAINã帰ã£ã¦æ¥ã¦é¢æ°ãreturnãã "accept() not ready"); return; }
acceptã®å®è¡ã¯ã³ã³ããã¹ãã¹ã¤ãããä¼´ãã¾ãããªã®ã§ãã®å¯¾çã¨ãã¦nginxã¯éå»ã«ã¦ã¼ã¶ç©ºéã§ã·ãªã¢ã©ã¤ãºãããããªaccept_mutextã¨ããæ©è½ãæä¾ãã¦ããã©ã«ãã§ãªã³ã«ãªã£ã¦ãã¾ããã(ç¾å¨ã¯ããã©ã«ãã§ãªãã«ãªã£ã¦ãã¾ããã)
ãªãã«ãªã£ãçç±ã¨ãã¦ã¯ã«ã¼ãã«ã«SO_REUSEPORTãEPOLLEXCLUSIVEã¨è¨ã£ãæ©è½ãæä¾ãããããã«ãªãã¦ã¼ã¶ç©ºéã§ãããããããå¹çããå¦çãè¡ããããã«ãªã£ãããã ã¨æããã¾ããSO_REUSETPORTã®æ§è½æ¸¬å®ã¯nginxãå ¬å¼ã§è¡ã£ãçµæãå ¬éããã¦ãã¾ãããããã«æ§è½åä¸ãã¦ããããã§ããããã¯ã©ããããã®ãã¨ããã¨è¤æ°ããã»ã¹ã§listenãã¥ã¼ãå¥ã ã«æã¤ãã¨ã§ã«ã¼ãã«ãå²ãæ¯ããè¡ãã¤ãã³ãã®çºçã1ããã»ã¹ã«éå®ããããã¨ãåºæ¥ãã¨ãããã®ã§ããããã®æ©è½ãããããã¨ã§ã¯ã©ã¤ã¢ã³ãããæ¥ç¶æã«ngx_event_accept()ã¯1ããã»ã¹ã®ã¿ãå¦çãè¡ãããã«ãªãã¾ãããã®æç¹ã§thundering herdã®å¯¾çã¨ãã¦åé¡ãªãã¨è¨ãããã§ãã
SO_REUSEPORTã¯åããã¼ã
ã¯ã¼ã«ã¼ããã»ã¹ãçµäºå¦çããã¦ããæä¸ã§ãã£ã¦ãã«ã¼ãã«ã¯listenãã¥ã¼ã«æ°è¦æ¥ç¶ãç©ã¿ç¶ãã¾ããlistenãã¥ã¼ã¯ããã»ã¹ãã¨ã«ããã®ã§ããã»ã¹ãçµäºãããlistenãã¥ã¼ã«ãã£ãã¯ã©ã¤ã¢ã³ãã«ã¤ãã¦ã¯æ¥ç¶ãã¨ã©ã¼ã¨ãªããåéãããã¨ãããããªåãã¨ãªãã¾ããããã対çããã®ãEPOLLEXCLUSIVEã¨ããæ©è½ã§ãã
ä¸æ¹ã EPOLLEXCLUSIVE ã¯ã listen ãã¥ã¼ã¯ä¸æ¬ã®ã¾ã¾ããã® listen ãã¥ã¼ãå¾ ã£ã¦ããè¤æ°ããã»ã¹ã® epoll_wait() ãå ¨é¨èµ·ããã®ã§ã¯ãªããï¼ã¤ä»¥ä¸ï¼ï¼ã¤ã¨ã¯éããªãï¼ã ãèµ·ããã¨ããæ©è½ã§ãã graceful shutdown ä¸ã¯ epoll_wait() ããã¦ããªãã¯ããªã®ã§ã listen ãã¥ã¼ã«æ¥ããªã¯ã¨ã¹ãã¯ä»ã®ã¯ã¼ã«ã¼ããã»ã¹ã® epoll_wait() ã«éç¥ãããåããã¼ããããã¾ããã
ã¨ã®ãã¨ã§ããããã»ã¹Aãçµäºãã¦ããéä¸ã¯epoll_waitã¯å®è¡ãã¦ããªãã®ã§ã¯ã©ã¤ã¢ã³ãã®æ¥ç¶ã¯ããã»ã¹A以å¤ã«å²ãæ¯ããããã¨ã§ããã»ã¹Aã¯å®å¿ãã¦çµäºã§ããã¨ãããã®ã®ããã§ããä»®ã«acceptãã¥ã¼ã«ã®ã¿å ¥ã£ãã³ãã¯ã·ã§ã³ãããå ´åã§ãepoll_waitã«ããæãããã®ã§åããã¼ãã¯ãªããªãã¯ãï¼