Nginx源码分析——main函数(二)

启动流程(二)

 

if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
    return 1;
}

识别NGINX_VAR环境变量,并且初始化&cycle->listening添加socket fd,并且重新设置ngx_listening_t中的字段。

if (ngx_preinit_modules() != NGX_OK) {
    return 1;
}

./src/core/ngx_module.c

初始化 ngx_modules列表的name和index, name由ngx_module_names列表得到,实际上最后利用的是cycle中的modules指针存放了这个模块列表的首地址。
cycle = ngx_init_cycle(&init_cycle);
if (cycle == NULL) {
    if (ngx_test_config) {
        ngx_log_stderr(0, "configuration file %s test failed",
        init_cycle.conf_file.data);
    }
    return 1;
}

./src/core/ngx_cycle.c

看方法名,就很好理解就是初始化cycle的数据结构,也是整个main函最核心的一块,包含大量的重要变量,包括监听列表、链接列表等等。后续重点去分析ngx_cycle_t数据结构的时候,再去讨论。
if (ngx_test_config) {
    if (!ngx_quiet_mode) {
        ngx_log_stderr(0, "configuration file %s test is successful",
            cycle->conf_file.data);
    }


    if (ngx_dump_config) {
        cd = cycle->config_dump.elts;
        for (i = 0; i < cycle->config_dump.nelts; i++) {
            ngx_write_stdout("# configuration file ");
            (void) ngx_write_fd(ngx_stdout, cd[i].name.data,
                cd[i].name.len);
            ngx_write_stdout(":" NGX_LINEFEED);

            b = cd[i].buffer;
            (void) ngx_write_fd(ngx_stdout, b->pos, b->last - b->pos);

            ngx_write_stdout(NGX_LINEFEED);
        }
    }
    return 0;
}

打印配置文件信息。

if (ngx_signal) {
    return ngx_signal_process(cycle, ngx_signal);    
}

./src/core/ngx_cycle.c

接收nginx的指令比如,-s就是指令说明,reload是指令的参数
./nginx -s reload

根据指令完成对nginx的操作,并且完成该进程。这个进程会向正在运行的nginx master进程发送对应的信号。

// TODO 这里待深入,以后作为补充
ngx_os_status(cycle->log);

在logs/error.log 日志文件里面写入状态日志

ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
    ngx_process = NGX_PROCESS_MASTER;
}

获取ngx_core_module模块配置,一般情况下ngx_process初始化的时候就是NGX_PROCESS_SINGLE,配置默认模式是master模式,所以ccf->master为true,ngx_process会被设置为NGX_PROCESS_MASTER;如果设置nginx.conf中的配置文件加入 

master_process off

结束掉之前启动的nginx进程,然后重新启动,就会发现只有一个进程,原来的worker进程没有了 

从上面的逻辑可以知道,为什么一定要重启nginx,命令处理是自识别master模式之前的,process模式的处理之前就已经退出了进程。
if (ngx_init_signals(cycle->log) != NGX_OK) {
    return 1;
}

./src/os/unix/ngx_process.c

nginx启动的时候,调用ngx_init_signals函数遍历  signals 中的信号并且注册信号处理函数。主要的处理函数有两个 (ngx_signal_handler或者SIG_IGN)
if (!ngx_inherited && ccf->daemon) {
    if (ngx_daemon(cycle->log) != NGX_OK) {
        return 1;
    }
    ngx_daemonized = 1;
}

if (ngx_inherited) {
    ngx_daemonized = 1;
}

实现进程守护。

if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
    return 1;
}

./src/core/ngx_cycle.c

如果是master模式,就将pid记录到pid文件里面。
if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
    return 1;
}

./src/core/ngx_log.c

如果nginx使用stderr,会将错误日志进行重定向。
if (ngx_process == NGX_PROCESS_SINGLE) {
    ngx_single_process_cycle(cycle);
} else {
    ngx_master_process_cycle(cycle);
}

return 0;

最后判断是master_process的模式,根据不同不是执行ngx_single_process_cycle或者是ngx_master_process_cycle,然后结束进程。

总结

本章只是将nginx源码中的main函数,大致代码走读了一些,里面还是有非常多的内容需要展开去将,后续也需要去构思一些应该如何去扩展下去讲。一般看一些nginx的书,上来就是讲nginx的数据结构等等,但是比较难以理解。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sinom21

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值