5
回答
Nginx的平滑重启、平滑升级是如何做到的啊?
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   
公司现在也在做个服务器,C++的,支持Windows/Linux,以前听说过Nginx可以在不间断提供服务的情况下升级,好神奇喔,因为我也做了蛮久C++的,但还是不了解这样的技术。
举报
天台道人
发帖于4年前 5回/4K+阅
共有5个答案 最后回答: 4年前
Nginx的进程分为master主进程和work工作进程,master进程主要管理事件信号接受和分发,所有的请求处理都由work进程处理并返回结 果,Nginx的平滑重启或重载配置文件等升级,首先是向master发送重启或重载配置文件信号,然后master告诉所有的work进程不再接受新的 请求,然后master另起新的work进程,最后告诉旧的work进程可以光荣退出了。
--- 共有 1 条评论 ---
天台道人原来是在工作安排上动了脑筋 不过,我还不是特别明白,向master进程发送重启信号之后,尤其是master程序体自己也需要升级的时候,master进程不也需要重启吗?master进程重启,这也就意味着master负责的事件信号接收和分发工作停止了?不是吗? 4年前 回复

平滑upgrade和普通reload的过程有区别,不能一概而论


在upgrade过程中,还涉及到3个信号(USR2、WINCH和QUIT)。

首先发送USR2信号给原master,原master进程会额外启动一个master进程和若干worker进程,新旧worker进程同时提供对外服务。

第二步发送WINCH信号,原worker进程停止服务并退出。

最后发送QUIT信号给原master使之退出,只保留新的master和worker。


这在Nginx的文档中有详细说明 http://wiki.nginx.org/CommandLine#Upgrading_To_a_New_Binary_On_The_Fly


Nginx官方提供的服务管理脚本的重载和升级:

do_reload() {
    #
    start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    return "$RETVAL"
}


do_upgrade() {
    OLDBINPIDFILE=$PIDFILE.oldbin

    do_configtest -q || return 6
    start-stop-daemon --stop --signal USR2 --quiet --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    sleep 1
    if [ -f $OLDBINPIDFILE -a -f $PIDFILE ]; then
        start-stop-daemon --stop --signal QUIT --quiet --pidfile $OLDBINPIDFILE --name $NAME
        RETVAL="$?"
    else
        echo $"Upgrade failed!"
        RETVAL=1
        return $RETVAL
    fi
}

一般来说,Linux上Nginx是以一个master进程和多个worker进程运行,master进程主要用来管理worker进程。

这两个特性涉及到Linux信号处理技术。
“信号(signal)是一种进程间通信机制,它给应用程序提供一种异步的软件中断,使应用程序有机会接受其他程序或终端发送的命令(即信号)。”
http://zachary-guo.iteye.com/blog/1358312

还有这个问题,你最好问问维护Tengine的  @shudu 和 维护SEnginx的 @InfoHunter 还有维护OpenResty 的 @章亦春 。

请看我之前写的一个ppt:http://www.slideshare.net/joshzhu/nginx-internals 第59、60页。可能需要翻墙。

值得一提的是热代码更新(upgrade)的实现:

  • 利用了exec()如果没有设置FD_CLOEXEC,就自然继承打开的fd;
  • 使用环境变量传递fd列表;
  • 使用getsockname()查地址。

顶部