8.3.2 ngx_cycle_t结构体

Nginx框架是围绕着ngx_cycle_t结构体来控制进程运行的。ngx_cycle_t结构体的prefix、conf_prefix、conf_file等字符串类型成员保存着Nginx配置文件的路径,从8.2节已经知道,Nginx的可配置性完全依赖于nginx.conf配置文件,Nginx所有模块的可定制性、可伸缩性等诸多特性也是依赖于nginx.conf配置文件的,可以想见,这个配置文件路径必然是保存在ngx_cycle_t结构体中的。

有了配置文件后,Nginx框架就开始根据配置项来加载所有的模块了,这一步骤会在ngx_init_cycle方法中进行(见8.3.3节)。ngx_init_cycle方法,顾名思义,就是用来构造ngx_cycle_t结构体中成员的,首先来介绍一下ngx_cycle_t中的成员(对于下面提到的connections、read_events、write_events、files、free_connections等成员,它们是与事件模块强相关的,本章将不做详细介绍,在第9章中会详述这些成员的意义)。


typedef struct ngx_cycle_s ngx_cycle_t;

struct ngx_cycle_s{

/保存着所有模块存储配置项的结构体的指针,它首先是一个数组,每个数组成员又是一个指针,这个指针指向另一个存储着指针的数组,因此会看到void**/

void**conf_ctx;

//内存池

ngx_pool_t*pool;

/日志模块中提供了生成基本ngx_log_t日志对象的功能,这里的log实际上是在还没有执行ngx_init_cycle方法前,也就是还没有解析配置前,如果有信息需要输出到日志,就会暂时使用log对象,它会输出到屏幕。在ngx_init_cycle方法执行后,将会根据nginx.conf配置文件中的配置项,构造出正确的日志文件,此时会对log重新赋值/

ngx_log_t*log;

/由nginx.conf配置文件读取到日志文件路径后,将开始初始化error_log日志文件,由于log对象还在用于输出日志到屏幕,这时会用new_log对象暂时性地替代log日志,待初始化成功后,会用new_log的地址覆盖上面的log指针/

ngx_log_t new_log;

//与下面的files成员配合使用,指出files数组里元素的总数

ngx_uint_t files_n;

/对于poll、rtsig这样的事件模块,会以有效文件句柄数来预先建立这些ngx_connection_t结构体,以加速事件的收集、分发。这时files就会保存所有ngx_connection_t的指针组成的数组,files_n就是指针的总数,而文件句柄的值用来访问files数组成员/

ngx_connection_t**files;

//可用连接池,与free_connection_n配合使用

ngx_connection_t*free_connections;

//可用连接池中连接的总数

ngx_uint_t free_connection_n;

/双向链表容器,元素类型是ngx_connection_t结构体,表示可重复使用连接队列/

ngx_queue_t reusable_connections_queue;

/动态数组,每个数组元素存储着ngx_listening_t成员,表示监听端口及相关的参数/

ngx_array_t listening;

/动态数组容器,它保存着Nginx所有要操作的目录。如果有目录不存在,则会试图创建,而创建目录失败将会导致Nginx启动失败。例如,上传文件的临时目录也在pathes中,如果没有权限创建,则会导致Nginx无法启动/

ngx_array_t pathes;

/单链表容器,元素类型是ngx_open_file_t结构体,它表示Nginx已经打开的所有文件。事实上,Nginx框架不会向open_files链表中添加文件,而是由对此感兴趣的模块向其中添加文件路径名,Nginx框架会在ngx_init_cycle方法中打开这些文件/

ngx_list_t open_files;

/单链表容器,元素的类型是ngx_shm_zone_t结构体,每个元素表示一块共享内存,共享内存将在第14章介绍/

ngx_list_t shared_memory;

//当前进程中所有连接对象的总数,与下面的connections成员配合使用

ngx_uint_t connection_n;

//指向当前进程中的所有连接对象,与connection_n配合使用

ngx_connection_t*connections;

//指向当前进程中的所有读事件对象,connection_n同时表示所有读事件的总数

ngx_event_t*read_events;

//指向当前进程中的所有写事件对象,connection_n同时表示所有写事件的总数

ngx_event_t*write_events;

/旧的ngx_cycle_t对象用于引用上一个ngx_cycle_t对象中的成员。例如ngx_init_cycle方法,在启动初期,需要建立一个临时的ngx_cycle_t对象保存一些变量,再调用ngx_init_cycle方法时就可以把旧的ngx_cycle_t对象传进去,而这时old_cycle对象就会保存这个前期的ngx_cycle_t对象/

ngx_cycle_t*old_cycle;

//配置文件相对于安装目录的路径名称

ngx_str_t conf_file;

/Nginx处理配置文件时需要特殊处理的在命令行携带的参数,一般是-g选项携带的参数/

ngx_str_t conf_param;

//Nginx配置文件所在目录的路径

ngx_str_t conf_prefix;

//Nginx安装目录的路径

ngx_str_t prefix;

//用于进程间同步的文件锁名称

ngx_str_t lock_file;

//使用gethostname系统调用得到的主机名

ngx_str_t hostname;

};


在构造ngx_cycle_t结构体成员的ngx_init_cycle方法中,上面所列出的pool内存池成员、hostname主机名、日志文件new_log和log、存储所有路径的pathes数组、共享内存、监听端口等都会在该方法中初始化。本章后续提到的流程、方法中可以随处见到ngx_cycle_t结构体成员的身影。