Nginx启动(ngx_init_cycle)
来源:互联网 发布:js单选框默认选中 编辑:程序博客网 时间:2024/06/05 19:15
1. ngx_cycle_t结构
该结构在./src/core/ngx_cycle.h文件中定义,如下。
- struct ngx_cycle_s {
- void ****conf_ctx; //配置上下文数组(含所有模块)
- ngx_pool_t *pool; //内存池
- ngx_log_t *log; //日志
- ngx_log_t new_log;
- ngx_connection_t **files; //连接文件
- ngx_connection_t *free_connections; //空闲连接
- ngx_uint_t free_connection_n; //空闲连接个数
- ngx_queue_t reusable_connections_queue; //再利用连接队列
- ngx_array_t listening; //监听数组
- ngx_array_t pathes; //路径数组
- ngx_list_t open_files; //打开文件链表
- ngx_list_t shared_memory; //共享内存链表
- ngx_uint_t connection_n; //连接个数
- ngx_uint_t files_n; //打开文件个数
- ngx_connection_t *connections; //连接
- ngx_event_t *read_events; //读事件
- ngx_event_t *write_events; //写事件
- ngx_cycle_t *old_cycle; //old cycle指针
- ngx_str_t conf_file; //配置文件
- ngx_str_t conf_param; //配置参数
- ngx_str_t conf_prefix; //配置前缀
- ngx_str_t prefix; //前缀
- ngx_str_t lock_file; //锁文件
- ngx_str_t hostname; //主机名
- };
该结构体的大小是确定的,sizeof(ngx_cycle_t)=224。
其中,
- pathes数组元素结构为ngx_path_t;
- open_files链表元素结构为ngx_open_file_t;
- shared_memory链表元素结构为ngx_shm_zone_t;
- listening数组元素结构为ngx_listening_t,该数组用来存放监听套接字。
各种数据结构关系图如下。
初始化过程如下。
- 调用ngx_timezone_update()更新时区,调用ngx_time_update()更新时间
- 创建大小为NGX_CYCLE_POOL_SIZE=16384B的内存池,并从中分配ngx_cycle_t结构
- 简单初始化,如记录pool指针、log指针
- 初始化配置前缀、前缀、配置文件、配置参数等字符串
- 初始化pathes数组
- 初始化open_files链表
- 初始化shared_memory链表
- 初始化listening数组
- 初始化resuable_connections_queue队列
- 从pool为conf_ctx分配空间
- 初始化hostname字符串
- 调用core模块的create_conf()
- 配置文件解析
- 调用core模块的init_conf()
- 遍历open_files链表中的每一个文件并打开
- 创建共享内存并初始化(新旧shared_memory链表的比较,相同的共享内存保留,旧的不同的共享内存被释放,新的被创建)
- (尝试5遍)遍历listening数组并打开所有侦听sockets(socket()->setsockopt()->bind()->listen())
- 提交新的cycle配置,并调用所有模块的init_module(实际上只有ngx_event_core_module模块定义了该callback,即只有ngx_event_module_init()被调用)
- 关闭或删除残留在old_cycle中的资源
- 释放多余的共享内存
- 关闭多余的侦听sockets
- 关闭多余的打开文件
它首先创建了一个内存池,然后在这个内存池上为cycle变量分配了一块存储空间。后续的所有初始化工作都为了填写这个cycle变量的各个成员字段。Nginx的内存池实现是相当的简单,但绝对不简陋;在web server的应用场景中是非常的有效。内存池的实现在src/core/ngx_palloc.h和src/core/ngx_palloc.c中。
NGX_CORE_MODULE类型的模块有:ngx_core_module、ngx_errlog_module、ngx_events_module和ngx_http_module等。
ngx_core_module定义在src/core/nginx.c文件中,create_conf钩子对应的函数为ngx_core_module_create_conf(),此函数就是创建ngx_core_conf_t配置结构。
ngx_errlog_module定义在src/core/ngx_log.c中,create_conf钩子没有对应的回调函数,为NULL。
ngx_events_module定义在src/event/ngx_event.c中,create_conf钩子没有对应的回调函数,为NULL。
ngx_http_module定义在src/http/ngx_http.c中,create_conf钩子没有对应的回调函数,为NULL。
由此可以看出,此处的循环执行create_conf回调函数,其实就只调用了ngx_core_module_create_conf()。
——————————————————————————————————ngx_core_conf_t————————————————————————————————————————————
Core模块的配置结构
如前文所述,core模块的callback有两个create_conf()和init_conf(),从名字就可以看出,一个创建配置结构,另一个初始化该配置结构。core模块的配置结构如下,存放配置文件中的核心指令,如deamon,master等。
./src/core/ngx_cycle.h
- typedef struct {
- ngx_flag_t daemon;
- ngx_flag_t master;
- ngx_msec_t timer_resolution;
- ngx_int_t worker_processes;
- ngx_int_t debug_points;
- ngx_int_t rlimit_nofile;
- ngx_int_t rlimit_sigpending;
- off_t rlimit_core;
- int priority;
- ngx_uint_t cpu_affinity_n;
- u_long *cpu_affinity;
- char *username; /* 用户名 */
- ngx_uid_t user; /* user ID */
- ngx_gid_t group; /* group ID*/
- ngx_str_t working_directory; /* */
- ngx_str_t lock_file; /* 用户名 */
- ngx_str_t pid;
- ngx_str_t oldpid; /* 以'.oldbin'结尾 */
- ngx_array_t env;
- char **environment;
- #if (NGX_THREADS)
- ngx_int_t worker_threads;
- size_t thread_stack_size;
- #endif
- } ngx_core_conf_t;
2.create_conf分析
前面完成了NGX_CORE_MODULE类型模块的配置结构创建工作,这里调用所有NGX_CORE_MODULE类型模块的init_conf回调函数,完成配置结构的初始化工作。同ceate_conf,其实此处也只是调用了ngx_core_module的ngx_core_module_init_conf()回调函数。对ceate_conf创建的配置结构进行初始化。其他几个NGX_CORE_MODULE没有init_conf回调函数。
———————————————————————————————init_conf———————————————————————————————————————
遍历open_files链表,打开所有文件(调用open)。起初,我们看到了对open_files链表的创建、初始化,却没有看到写需要打开的文件名数据到链表中;其实,填写文件名数据就是在解析配置文件的时候完成的。除此之外,很多很多的数据初始化都是在解析配置文件的时候完成。执行了打开文件操作后,open_files链表就不光保存了文件名了,还保存了文件描述符等信息,足够以后读写文件之用了。
这部分复杂的代码就是为完成所有共享内存的创建及初始化,后面再专门分析Nginx对共享内存的管理及使用。
遍历listening数组,打开所有的监听套接口(依次进行socket、bind、listen),同时设置一些socket选项及文件描述符属性,如非阻塞等。
执行所有模块的init_module操作,看名字为对模块进行初始化。 浏览源码,发现包括几个NGX_CORE_MODULE类型的模块在内的绝大多数模块都没有这个init回调函数。究竟哪些模块才使用这个回调接口呢?动用搜索功能,终于找到了一个模块使用了这个回调接口,它就是ngx_event_core_module。
- Nginx启动(ngx_init_cycle)
- 12.Nginx启动流程之ngx_init_cycle
- Nginx之main初探ngx_init_cycle()(上)
- nginx源码学习(二)ngx_init_cycle(&init_cycle)函数解析
- nginx学习十二 ngx_cycle_t 和 ngx_init_cycle
- nginx源码阅读(二).初始化:main函数及ngx_init_cycle函数
- ngx_init_cycle()详解
- ngx_init_cycle()详解
- ngx_init_cycle()详解
- Nginx启动详解(未完)
- Nginx启动初始化(1)
- nginx启动脚本(样本)
- ngx_init_cycle的详细分析
- ngx_init_cycle 学习笔记
- nginx启动
- nginx 启动
- nginx 启动
- nginx启动
- openwrt定制管理
- Nginx启动初始化(1)
- ubuntu下android开发工具的安装
- 轻松搞定javascript预解析机构(搞定后,一切有关变态面试题都是浮云)
- CC_SYNTHESIZE
- Nginx启动(ngx_init_cycle)
- struts2---防重复提交解析
- 强大Linux网站
- Ubuntu 或 UbuntuKyKin14.04 Unity桌面风格与Gnome桌面风格的切换
- Dalvik和JVM的区别?
- IPAD SSH 不成功!fix it
- 读《深入浅出MySQL:数据库开发、优化与管理维护》,学习了第一章
- VM(虚拟机技术)保护
- Nginx配置项解析