Nginx源码分析--平滑升级原理

3 篇文章 0 订阅

一、Nginx平滑升级指令

Nginx的MakeFile文件:


default:        build

clean:
        rm -rf Makefile objs

build:
        $(MAKE) -f objs/Makefile

install:
        $(MAKE) -f objs/Makefile install

modules:
        $(MAKE) -f objs/Makefile modules

upgrade:
        /home/nginx_rtmp//sbin/nginx -t

        kill -USR2 `cat /home/nginx_rtmp//logs/nginx.pid`
        sleep 10
        test -f /home/nginx_rtmp//logs/nginx.pid.oldbin

        kill -QUIT `cat /home/nginx_rtmp//logs/nginx.pid.oldbin`

将编译好的新Nginx可执行程序,替换原有的旧Nginx程序后,执行make upgrade即可。

二、Nginx平滑升级的源码实现

1、nginx启动时,初始化信号处理函数。

static void
ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext)
{
.........
.........
        case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
            if (ngx_getppid() == ngx_parent || ngx_new_binary > 0) {

                /*
                 * Ignore the signal in the new binary if its parent is
                 * not changed, i.e. the old binary's process is still
                 * running.  Or ignore the signal in the old binary's
                 * process if the new binary's process is already running.
                 */

                action = ", ignoring";
                ignore = 1;
                break;
            }

            ngx_change_binary = 1;
            action = ", changing binary";
            break;
.........
.........
}

ngx_config.h中
#define NGX_REOPEN_SIGNAL        USR1
#define NGX_CHANGEBIN_SIGNAL     USR2

2、发送NGX_CHANGEBIN_SIGNAL信号

信号处理接收到信号后,将ngx_change_binary 置 1。

void
ngx_master_process_cycle(ngx_cycle_t *cycle)
{
.........
.........
        if (ngx_change_binary) {
            ngx_change_binary = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary");
            ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
        }
.........
.........
}
保存监听的socketfd
将保存旧的nginx master进程pid的文件重命名
创建子进程
ngx_exec_new_binary
ngx_set_environment
cycle.listening.elts
ngx_rename_file
ngx_execute
ngx_spawn_process
ngx_execute_proc
execve

execve():会保留父进程的文件描述符。可以重用父进程的监听套接字。
execve(): By default, file descriptors remain open across an execve(). File descriptors that are marked close-on-exec are closed; see the description of FD_CLOEXEC in fcntl(2). (If a file descriptor is closed, this will cause the release of all record locks obtained on the underlying file by this process. See fcntl(2) for details.) POSIX.1-2001 says that if file descriptors 0, 1, and 2 would otherwise be closed after a successful execve(), and the process would gain privilege because the set-user_ID or set-group_ID permission bit was set on the executed file, then the system may open an unspecified file for each of these file descriptors. As a general principle, no portable program, whether privileged or not, can assume that these three file descriptors will remain closed across an execve().

3、新的可执行程序运行

static void
ngx_execute_proc(ngx_cycle_t *cycle, void *data)
{
.........
.........
    if (execve(ctx->path, ctx->argv, ctx->envp) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "execve() failed while executing %s \"%s\"",
                      ctx->name, ctx->path);
    }
.........
.........
}
int ngx_cdecl
main(int argc, char *const *argv)
{
.........
.........
    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }
.........
.........
}

ngx_int_t
ngx_open_listening_sockets(ngx_cycle_t *cycle)
{
.........
.........
            if (ls[i].fd != (ngx_socket_t) -1) {
                /*对于继承的socket,实际上是运行到这里*/
                continue;
            }


            if (ls[i].inherited) {

                /* TODO: close on exit */
                /* TODO: nonblocking */
                /* TODO: deferred accept */

                continue;
            }
.........
.........
}

在这里插入图片描述
4、关闭旧的nginx master

kill -QUIT `cat /home/nginx_rtmp//logs/nginx.pid.oldbin`
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值