nginx主函数分析

nginx的源代码结构如图:

入口程序, 及主程序位于src/core/nginx.c中的main函数, 下面来简单的过下这个主函数做了些什么事情:

  1. ngx_debug_init() 调试相关的初始化, 用于开发环境的调试
  2. ngx_strerror_init() 错误信息相关的初始化, 如果初始化失败, 则直接退出
  3. ngx_get_options() 获取命令行的参数选项,并将对应的参数值赋值给具体的变量, 比如ngx_show_version, ngx_show_help之类的变量, 继而后面可选择性的执行相应的处理。
  4. 接下来基本上是根据命令行参数,是否显示版本号, 是否显示帮助, 是否显示配置信息给用户呈现一些提示性的信息。
  5. ngx_max_sockets = -1; 初始化ngx_max_sockets ,该变量在os/unix/ngx_posix_init.c中定义, 为ngx_int_t类型。
  6. ngx_time_init() 时间初始化
  7. ngx_regex_init() 正则初始化, 如果启用PCRE的话会进行正则的初始化。
  8. ngx_pid = ngx_getpid()  获取当前进程ID
  9. log = ngx_log_init(ngx_prefix)   初始化日志对象, 如果初始化失败, 则直接退出。
  10. ngx_ssl_init() 在启用了nginx的openssl的时候, 会对ssl进行初始化
  11. ngx_memzero(&init_cycle, sizeof(ngx_cycle_t)) 将初始化周期对象初始化为全零状态。
  12. init_cycle.log = log; ngx_cycle = &init_cycle; 初始化ngx_cycle对象。该对象是在core/ngx_cycle.c中定义的volatile ngx_cycle_t  *ngx_cycle;
  13. 分配内存池init_cycle.pool = ngx_create_pool(1024, log); 为ngx_cycle.pool对象创建1024B的内存池。内存池初始化失败就直接返回。
  14. ngx_save_argv(&init_cycle, argc, argv)  将命令行参数保存到ngx_os_argv、ngx_argc以及ngx_argv这几个全局的变量中。这算是一个备份存储,方便以后master进程做热代码替换之用。 如果保存失败也会直接退出。 这个过程会用到init_cycle的log对象, 对内存的分配做日志性记录之用。
  15. ngx_process_options(&init_cycle) : 初始化init_cycle中的一些如: conf_file,prefix,conf_prefix等字段, 失败也是直接返回。
  16. ngx_os_init(log) : 完成操作系统的一些信息获取,如内存页面大小、系统限制资源,ngx_pagesize,ngx_cacheline_size,最大连接数ngx_max_sockets等。 所有的这些资源都将会被保存在对应的全局变量中,因此后续访问将会很便利。同样失败会退出。
  17. ngx_crc32_table_init(): 初始化一个做循环冗余校验的表,由此可以看出后续的循环冗余校验将采用高效的查表法。 失败直接退出。
  18. ngx_add_inherited_sockets(&init_cycle) : 通过环境变量NGINX完成socket的继承,继承来的socket将会放到init_cycle的listening数组中。在NGINX环境变量中,每个socket中间用冒号或分号隔开。完成继承同时设置全局变量ngx_inherited为1。失败直接退出。
  19. 将nginx中的模块全部索引起来, 其中所有模块在编译后的ngx_modules.c中定义, 这个变量是在编译后才出现的,和编译条件密切相关, 也就是说nginx需要添加模块, 需要重新编译. ngx_max_module = 0;
        for (i = 0; ngx_modules[i]; i++) {
            ngx_modules[i]->index = ngx_max_module++;
        }
  20. cycle = ngx_init_cycle(&init_cycle) : 对ngx_cycle结构进行初始化,这里是nginx启动核心之处, 会将很多东西放在init_cycle中.详细见ngx_cycle.c中的 ngx_init_cycle方法.初始化失败会直接退出。
  21. 如果有信号进来, 进入ngx_signal_process处理信号。
        if (ngx_signal) {
            return ngx_signal_process(cycle, ngx_signal);
        }
  22. ngx_os_status(cycle->log) 操作系统状态日志记录
  23. 获取核心模块的配置信息:ngx_cycle = cycle;
        ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
  24. ngx_init_signals(cycle->log) : 非win32系统信号初始化。注册一堆信号处理程序,需要注册的信号及相应的信号处理函数被放在一个类型为ngx_signal_t的数组signals中。数组定义在src/os/unix/ngx_process.c中。ngx_signal_t结构类型定义了信号值,信号名字,信号对应动作名以及信号处理函数。失败退出。
  25. ngx_daemon(cycle->log) : ngx_daemon肯定就是用来实现守护进程的函数了, 有需要写server程序的,可以直接copy这段代码实现守护进程。代码实现位于 ./src/os/unix/ngx_daemon.c , 还是非win32系统。
  26. ngx_create_pidfile(&ccf->pid, cycle->log) : 创建一个pid文件, 玩过nginx的都知道, 启动的时候就会生成一个pid文件, 那个文件的产生就是这里来的。
  27. 最后根据使用单进程还是多进程的方式, 当然服务器都是多进程, 只有调试的时候会启用单进程, 这里分别调用ngx_single_process_cycle(cycle)来单进程处理。ngx_master_process_cycle(cycle)多进程处理, 其实这两个函数都是一个无限循环函数,实现服务的功能。


以上就是主功能的完整过程。 后续会对每个单独的步骤做详细的介绍。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值