1、以下是我阅读nginx(1.13.2版本)源码的一些心得,个人觉得学一个东西最好学它的思想,学会举一反三。因为互联网的东西实在太多 了。


先来看看nginx的整体启动流程,因为是从整体上去了解原理,细节的东西省去,


比如ssl初始化等操作。(nginx.c)。



main(int argc, char *const *argv){ 
 
 
 

        //定义一些变量 
 
 
 

         
 
 
 

        ngx_debug_init();//调试初始化,不管它 
 
 
 

        ngx_strerror_init();//方法里面没有逻辑,直接返回NGX_OK了



     ngx_get_options(argc, argv);//获取命令行参数,并且赋值给静态变量,比如nginx -v 这个v就会赋值ngx_show_version = 1;后面程序运行时判断nginx_show_version如果等于1,直接输出nginx的版本号就返回了,不会继续执行



ngx_time_init(); //时间初始化,应该是给后面那些定时任务使用的,更新时间的时候有一个互斥锁 
 
 
 

        ngx_pid = ngx_getpid(); //获取主进程的ID 
 
 
 

        log = ngx_log_init(ngx_prefix); //初始化日志结构体ngx_log_s,包括打开文件名称,句柄等信息 
 
 
 

        ngx_memzero(&init_cycle, sizeof(ngx_cycle_t)); //给init_cycle分配内存空间并清空,nginx是围绕init_cycle来运行的,阅读源码时可以看着init_cycle结构体来学习 
 
 
 

        init_cycle.log = log; //把log指针赋值给init_cycle结构体的log属性 
 
 
 

        ngx_cycle = &init_cycle; //ngx_cycle是一个全局变量 
 
 
 

        init_cycle.pool = ngx_create_pool(1024, log);//申请一个2014字节的内存空间,空间必然是要使用的 
 
 
 

        ngx_save_argv(&init_cycle, argc, argv);把参数赋值给一些全局变量,方便后面使用 
 
 
 

        ngx_crc32_table_init();//这个可以看下crc32查找算法,这里初始化这个功能,后面用到,如果不看的话理解为一个用于快速搜索的结构体就好 
 
 
 

        ngx_preinit_modules();//对已经编译的模块进行清点编号顺序,方便后面使用,解析放到文章末尾 
 
 
 

        cycle = ngx_init_cycle(&init_cycle); //对结构体进行初始化操作,这个是整个nginx启动的核心,放在第二章学习 
 
 
 

        ngx_init_signals(cycle->log);//对信号进行注册,解释看文章末尾 
 
 
 

         if (ngx_process == NGX_PROCESS_SINGLE) {   
 
 
 

           ngx_single_process_cycle(cycle);//单进程直接进入,核心处理代码,放在第三章学习 
 
 
 

       } else { 
 
 
 

           ngx_master_process_cycle(cycle); //多个work进程进入 
 
 
 

       } 
 
 
 

   }





ngx_preinit_modules解析:


/* 

 

  ngx_int_t ngx_preinit_modules(void) 

 

  { 

 

  - ngx_max_module = 0; 

 

  - for (i = 0; ngx_modules[i]; i++) { 

 

  -     ngx_modules[i]->index = ngx_max_module++; 

 

  - } 

 

  } 

 

  return NGX_OK; 

 

  }


 额!!!这个循环中的ngx_modules数组好像没见定义,难不成是火星来的?当然不是,如其名,这就是一个存储所有模块的信息,包括自己开发的模块都会放到这个数组中,而这个神秘的数组却是在自动编译的时候生成的,位于objs/ngx_modules.c文件中。这个循环的目的是清晰可见的——对所有模块进行索引编号,方便以后访问;同时借助ngx_max_module对所有模块进行了一次点数,确定究竟有多少模块。而神秘数组ngx_modules的长相大概如下:


- ngx_module_t *ngx_modules[] = { 

 

  -     &ngx_core_module, 

 

  -     &ngx_errlog_module, 

 

  -     &ngx_conf_module, 

 

  -     &ngx_events_module, 

 

  -     &ngx_event_core_module, 

 

  -     &ngx_epoll_module, 

 

  -     &ngx_openssl_module, 

 

  -     &ngx_http_module, 

 

  -     。。。 

 

  - }; 

 

             

 

       */







ngx_process_signals:


 注册一堆信号处理程序,需要注册的信号及相应的信号处理函数被放在一个类型为ngx_signal_t的数组signals中。数组定义在src/os/unix/ngx_process.c中。ngx_signal_t结构类型定义了信号值,信号名字,信号对应动作名以及信号处理函数。