Nginx源码分析 - 主流程篇 - 平滑重启和信号控制(10)

目录

一、平滑重启

二、信号处理

一、平滑重启

ngx_add_inherited_sockets主要用于继承Socket文件句柄。

Nginx有平滑重启的功能,通过平滑重启,可以让用户无感知并且不中断。

#平滑重启  
sudo kill -HUP `cat /usr/local/nginx-1.4.7/nginx.pid`  

Nginx支持热切换,为了保证切换之后的套接字不丢失,就需要Nginx继承原先的socket(用户正在连接Nginx的时候的文件句柄)。

ngx_add_inherited_sockets正是做了这个工作

套接字会放在“NGINX”的全局环境变量中。

继承后的socket文件句柄放到ngx_cycle.listening数组中。

    /* 初始化socket端口监听,例如打开80端口监听;
     * Nginx支持热切换,为了保证切换之后的套接字不丢失,
     * 所以需要采用这一步添加继承的Socket套接字,套接字会放在NGINX的全局环境变量中*/
    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }

NGINX宏变量的值,值为客户端的socket fd句柄:

NGINX="16000:16500:16600;"

具体函数实现:

/**
 * Nginx支持热切换,为了保证切换之后的套接字不丢失,所以需要采用这一步添加继承的Socket套接字,套接字会放在NGINX的全局环境变量中
 * 初始化继承的sockets
 * 函数通过环境变量NGINX完成socket的继承,继承来的socket将会放到init_cycle的listening数组中。
 * 在NGINX环境变量中,每个socket中间用冒号或分号隔开。完成继承同时设置全局变量ngx_inherited为1。
 */
static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle)
{
    u_char           *p, *v, *inherited;
    ngx_int_t         s;
    ngx_listening_t  *ls;
    inherited = (u_char *) getenv(NGINX_VAR);
    if (inherited == NULL) {
        return NGX_OK;
    }
    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,"using inherited sockets from \"%s\"", inherited);
    if (ngx_array_init(&cycle->listening, cycle->pool, 10,sizeof(ngx_listening_t))
        != NGX_OK)
    {
        return NGX_ERROR;
    }
    for (p = inherited, v = p; *p; p++) {
        if (*p == ':' || *p == ';') {
            s = ngx_atoi(v, p - v);
            if (s == NGX_ERROR) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,"invalid socket number \"%s\" in " NGINX_VAR
                       " environment variable, ignoring the rest"" of the variable", v);
                break;
            }
            v = p + 1;
            ls = ngx_array_push(&cycle->listening);
            if (ls == NULL) {
                return NGX_ERROR;
            }
            ngx_memzero(ls, sizeof(ngx_listening_t));
            ls->fd = (ngx_socket_t) s;
        }
    }
    if (v != p) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,"invalid socket number \"%s\" in " NGINX_VAR" environment variable, ignoring", v);
    }
    ngx_inherited = 1;
    return ngx_set_inherited_sockets(cycle);
}

二、信号处理

当我们使用./nginx -s stop|reload|quit  类似这样的命令的时候,就是给Nginx发送了一个信号。
信号可以控制Nginx进程的重启、停止、退出等操作。通过获取已经启动的Nginx的进程PID,对进程发送信号操作。
Nginx的进程ID pid一般会放置到/usr/local/nginx-1.4.7/nginx.pid。

    /* 处理信号;例如./nginx -s stop,则处理Nginx的停止信号 */
    if (ngx_signal) {
        return ngx_signal_process(cycle, ngx_signal);
    }

ngx_signal变量是在ngx_get_options方法中。ngx_signal主要用于标识是否是属于信号操作。例如:./nginx -s stop|reload|quit

                /* ngx_signal 是否有信号  ./nginx -s stop|reload|quit */
            case 's':
                if (*p) {
                    ngx_signal = (char *) p;
 
                } else if (argv[++i]) {
                    ngx_signal = argv[i];
 
                } else {
                    ngx_log_stderr(0, "option \"-s\" requires parameter");
                    return NGX_ERROR;
                }
 
                if (ngx_strcmp(ngx_signal, "stop") == 0
                    || ngx_strcmp(ngx_signal, "quit") == 0
                    || ngx_strcmp(ngx_signal, "reopen") == 0
                    || ngx_strcmp(ngx_signal, "reload") == 0)
                {
                    ngx_process = NGX_PROCESS_SIGNALLER;
                    goto next;
                }
 
                ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);
                return NGX_ERROR;

 

参考文章:

1.https://initphp.blog.csdn.net/article/details/51841597

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值