Nginx学习——启动框架
来源:互联网 发布:淘宝买二手电脑 编辑:程序博客网 时间:2024/05/21 18:50
Nginx启动时框架处理流程
下图包含了Nginx框架在启动阶段执行的所有基本流程:
下面的简要源码是对上面步骤的说明:
第1步:
在src\core\nginx.c的main函数中实现:
主要语句:
/*第1步:调用ngx_process_options方法设置配置文件路径等参数*/ if (ngx_process_options(&init_cycle) != NGX_OK) { return 1;}
第2步:
在src\core\nginx.c的main函数中实现:
主要语句:
/*第2步Nginx不重启master进程而启动新版本的Nginx程序,也就是平滑升级。通过环境变量NGINX完成socket的继承,继承来的socket将会放到init_cycle的listening数组中。在NGINX的环境变量中,每个socke中间用冒号或分号隔开。完成继承同时设置全局变量ngx_inherited为1.*/ if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) { return 1;}
第3-8步都在:src\core\ngx_cycle.c中ngx_init_cycle实现,在main函数调用ngx_init_cycle源码如下:
/*调用ngx_init_cycle()函数,这里会初始化很多东西到变量cycle,是nginx启动初始化的核心之处*/cycle = ngx_init_cycle(&init_cycle);
第3步:
/*流程图第3步:在for循环中,调用NGX_CORE_MODULE类型模块的ceate_conf回调,创建相应的配置结构存储空间,然后将这个配置结构存储空间的地址保存到conf_ctx数组的对应单元处。*/ for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_CORE_MODULE) { continue; } module = ngx_modules[i]->ctx; if (module->create_conf) { rv = module->create_conf(cycle); if (rv == NULL) { ngx_destroy_pool(pool); return NULL; } cycle->conf_ctx[ngx_modules[i]->index] = rv; }}
第4步:
/*第4步:这里将完成对配置文件的解析工作,做过Nginx模块开发的都清楚——解析配置文件的时候,将会完成每个指令的set回调,这个set回调函数一般都是用于将配置数据填写到配置结构中。*/ if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) { environ = senv; ngx_destroy_cycle_pools(&conf); return NULL; } if (ngx_test_config && !ngx_quiet_mode) { ngx_log_stderr(0, "the configuration file %s syntax is ok", cycle->conf_file.data);}
第5步:
/*第五步:这里调用所有NGX_CORE_MODULE类型模块的init_conf回调函数,完成配置结构的初始化工作。*/ for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_CORE_MODULE) { continue; } module = ngx_modules[i]->ctx; if (module->init_conf) { if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index]) == NGX_CONF_ERROR) { environ = senv; ngx_destroy_cycle_pools(&conf); return NULL; } }}
第6步:
/*第6步:此处for循环是在遍历链表open_files遍历open_files链表,打开所有文件(调用open)。起初,我们看到了对open_files链表的创建、初始化,却没有看到写需要打开的文件名数据到链表中;其实,填写文件名数据就是在解析配置文件的时候完成的。除此之外,很多很多的数据初始化都是在解析配置文件的时候完成。执行了打开文件操作后,open_files链表就不光保存了文件名了,还保存了文件描述符等信息,足够以后读写文件之用了。*/ for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; file = part->elts; i = 0; } if (file[i].name.len == 0) { continue; }/*根据链表中存储的文件名来打开对应的文件*/ file[i].fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND, NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS); ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0, "log: %p %d \"%s\"", &file[i], file[i].fd, file[i].name.data); if (file[i].fd == NGX_INVALID_FILE) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, ngx_open_file_n " \"%s\" failed", file[i].name.data); goto failed; }#if !(NGX_WIN32) if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fcntl(FD_CLOEXEC) \"%s\" failed", file[i].name.data); goto failed; }#endif}/*第6步:同上面的open_files,此处遍历链表shared_memory,初始化各个共享内存段*/ for (i = 0; /* void */ ; i++) {ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; shm_zone = part->elts; i = 0; } if (shm_zone[i].shm.size == 0) { ngx_log_error(NGX_LOG_EMERG, log, 0, "zero size shared memory zone \"%V\"", &shm_zone[i].shm.name); goto failed; } shm_zone[i].shm.log = cycle->log; opart = &old_cycle->shared_memory.part; oshm_zone = opart->elts; for (n = 0; /* void */ ; n++) { if (n >= opart->nelts) { if (opart->next == NULL) { break; } opart = opart->next; oshm_zone = opart->elts; n = 0; } if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) { continue; } if (ngx_strncmp(shm_zone[i].shm.name.data, oshm_zone[n].shm.name.data, shm_zone[i].shm.name.len) != 0) { continue; } if (shm_zone[i].tag == oshm_zone[n].tag && shm_zone[i].shm.size == oshm_zone[n].shm.size) { shm_zone[i].shm.addr = oshm_zone[n].shm.addr; if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data) != NGX_OK) { goto failed; } goto shm_zone_found; } ngx_shm_free(&oshm_zone[n].shm); break; }/*第6步:下面三步就完成共享内存的创建和初始化*/ if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) { goto failed; } if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) { goto failed; } if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) { goto failed; } shm_zone_found: continue; }
第7步:
/*第七步:遍历listening数组,打开所有的监听套接口(依次进行socket、bind、listen),同时设置一些socket选项及文件描述符属性,如非阻塞等。*/ if (ngx_open_listening_sockets(cycle) != NGX_OK) { goto failed; } if (!ngx_test_config) { ngx_configure_listening_sockets(cycle); }
第8步:
/*第8步:执行所有模块的init_module操作,看名字为对模块进行初始化。*/ for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_module) { if (ngx_modules[i]->init_module(cycle) != NGX_OK) { /* fatal */ exit(1); } } }
第9步-16步又回到main函数中执行:
/*到此就基本完成了Nginx的启动初始化过程了,即将开始进程相关的工作,这里做最重要的是ngx_master_process_cycle这个过程,在这个过程里实现了master-worker模式的进程模型,也是生成环境下nginx的常用模型。*/ if (ngx_process == NGX_PROCESS_SINGLE) {/*第9、10步*/ ngx_single_process_cycle(cycle); } else {/*第11-16步*/ ngx_master_process_cycle(cycle); }
参考
深入理解Nginx
http://www.alidata.org/archives/1092
0 0
- Nginx学习——启动框架
- Nginx学习(12)—Nginx启动流程
- Nginx学习之十一-Nginx启动框架处理流程
- Nginx学习之十一-Nginx启动框架处理流程
- Nginx学习之十一-Nginx启动框架处理流程
- Nginx学习之十一-Nginx启动框架处理流程
- Nginx学习笔记——启动、停止
- Nginx学习(18)—事件处理框架
- nginx学习笔记三(nginx启动框架的处理流程)
- Nginx启动框架处理流程
- nginx 源码学习笔记(十九)—— nginx启动过程函数调用图
- nginx 源码学习笔记(十九)—— nginx启动过程函数调用图
- Nginx学习——Nginx启动、停止、重启和信号控制以及平滑升级
- Nginx学习笔记(十三):Nginx启动流程
- nginx学习十一 nginx启动流程
- ABP 框架从源码学习——abp框架启动和结束(1)
- ABP 框架从源码学习——abp框架启动核心类AbpBootstrapper(2)
- Nginx学习之一——编译nginx
- ★ HDU 3315 求KM最大时,要求改动最少
- gwgwgwgwgw
- 【虚拟化实战】在线沙龙请您参加(19:30 周一 7月28日)
- ifeq ifneq ifdef ifndef
- HDU 1242 Rescue (BFS+优先队列)
- Nginx学习——启动框架
- Robbie's Notes on File System Security in Linux (and comparison to Windows NT)
- java jxl创建/读取/修改Excel 操作Excel
- wtw2t2t2t2
- 嵌套iframe页面中的JS调用
- IOS_Learing高级开发~Runtime(一)
- Red and Black(DFS)
- 兼谈如何使用AForge.NET控件
- cocos2d游戏学习一:CCNode