链接:http://blog.csdn.net/livelylittlefish/article/details/7247080
Content
0.序
1. ngx_cycle_t结构
2. ngx_init_cycle()分析
3.注意问题
3.1如何调用CORE模块的callback函数?
3.2 open_files链表中的文件名何时初始化?
4.小结
0.序
Nginx的大部分初始化工作主要围绕一个类型为ngx_cycle_t类型的全局变量(cycle)展开。本文重点介绍全局变量ngx_cycle的初始化。
实现文件:./src/core/ngx_cycle.c。.表示nginx-1.0.4代码目录,本文为/usr/src/nginx-1.0.4。
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。
其中,
-
open_files链表元素结构为ngx_open_file_t;
-
shared_memory链表元素结构为ngx_shm_zone_t;
-
listening数组元素结构为ngx_listening_t,该数组用来存放监听套接字。
各种数据结构关系图如下。
2. ngx_init_cycle()分析
初始化过程如下。
-
调用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队列
-
配置文件解析
-
调用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
-
关闭多余的打开文件
具体请参考附录代码,不需要细究每一步实现,重要的是要搞清楚其初始化流程。初始化过程中全局结构ngx_cycle结构图如下。
main()调用ngx_init_cycle()后,全局变量ngx_cycle的内容如下。可对比上图查看
-
(gdb) p *ngx_cycle
-
$3 = {
-
conf_ctx = 0x6b1060,
-
pool = 0x6b0280,
-
log = 0x6b02e8,
-
new_log = {
-
log_level = 4,
-
file = 0x6b0558,
-
connection = 0,
-
handler = 0,
-
data = 0x0,
-
action = 0x0
-
},
-
files = 0x0,
-
free_connections = 0x0,
-
free_connection_n = 0,
-
reusable_connections_queue = {
-
prev = 0x6b0330,
-
next = 0x6b0330
-
},
-
listening = {
-
elts = 0x6b0930,
-
nelts = 1,
-
size = 184,
-
nalloc = 10,
-
pool = 0x6b0280
-
},
-
pathes = {
-
elts = 0x6b04d8,
-
nelts = 5,
-
size = 8,
-
nalloc = 10,
-
pool = 0x6b0280
-
},
-
open_files = {
-
last = 0x6b0398,
-
part = {
-
elts = 0x6b0528,
-
nelts = 2,
-
next = 0x0
-
---Type <return> to continue, or q <return> to quit---
-
},
-
size = 48,
-
nalloc = 20,
-
pool = 0x6b0280
-
},
-
shared_memory = {
-
last = 0x6b03d0,
-
part = {
-
elts = 0x6b08e8,
-
nelts = 0,
-
next = 0x0
-
},
-
size = 72,
-
nalloc = 1,
-
pool = 0x6b0280
-
},
-
connection_n = 1024,
-
files_n = 0,
-
connections = 0x0,
-
read_events = 0x0,
-
write_events = 0x0,
-
old_cycle = 0x0,
-
conf_file = {
-
len = 32,
-
data = 0x6b04b7 "/usr/local/nginx/conf/nginx.conf"
-
},
-
conf_param = {
-
len = 0,
-
data = 0x6b04d8 "\240{l"
-
},
-
conf_prefix = {
-
len = 22,
-
data = 0x6b0490 "/usr/local/nginx/conf//usr/local/nginx//usr/local/nginx/conf/nginx.conf"
-
},
-
prefix = {
-
len = 17,
-
data = 0x6b04a6 "/usr/local/nginx//usr/local/nginx/conf/nginx.conf"
-
},
-
lock_file = {
-
---Type <return> to continue, or q <return> to quit---
-
len = 33,
-
data = 0x6ccee0 "/usr/local/nginx/logs/nginx.lock.accept"
-
},
-
hostname = {
-
len = 4,
-
data = 0x6b11c0 "yu30"
-
}
-
}
3.注意问题
3.1如何调用CORE模块的callback函数?
即如可调用core模块的create_conf()和init_conf()?
(1) callback定义
file: ./src/core/ngx_conf_file.h
-
typedef struct { //定义core模块上下文类型
-
ngx_str_t name; //模块名,即ngx_core_module_ctx结构体对象的ngx_string("core")
-
void *(*create_conf)(ngx_cycle_t *cycle); //创建配置的callback
-
char *(*init_conf)(ngx_cycle_t *cycle, void *conf); //初始化配置的callback
-
} ngx_core_module_t
(2) callback初始化
静态初始化ngx_core_module_ctx和ngx_core_module结构。在编译期间就已确定CORE模块的callback了。
file: ./src/core/nginx.c
-
static ngx_core_module_t ngx_core_module_ctx = { //定义ngx_core_module模块上下文,改方式属于静态初始化
-
ngx_string("core"),
-
ngx_core_module_create_conf,
-
ngx_core_module_init_conf
-
};
-
-
-
ngx_module_t ngx_core_module = { //定义ngx_core_module模块,也是静态初始化
-
NGX_MODULE_V1,
-
&ngx_core_module_ctx, /* module context */
-
ngx_core_commands, /* module directives */
-
NGX_CORE_MODULE, /* module type */
-
NULL, /* init master */
-
NULL, /* init module */
-
NULL, /* init process */
-
NULL, /* init thread */
-
NULL, /* exit thread */
-
NULL, /* exit process */
-
NULL, /* exit master */
-
NGX_MODULE_V1_PADDING
-
}
静态初始化ngx_core_commands结构。
file: ./src/core/nginx.c
-
static ngx_command_t ngx_core_commands[] = { //静态初始化core模块的命令
-
-
{ ngx_string("daemon"),
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
-
ngx_conf_set_flag_slot,
-
0,
-
offsetof(ngx_core_conf_t, daemon),
-
NULL },
-
-
{ ngx_string("master_process"),
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
-
ngx_conf_set_flag_slot,
-
0,
-
offsetof(ngx_core_conf_t, master),
-
NULL },
-
-
{ ngx_string("timer_resolution"),
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
-
ngx_conf_set_msec_slot,
-
0,
-
offsetof(ngx_core_conf_t, timer_resolution),
-
NULL },
-
-
{ ngx_string("pid"),
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
-
ngx_conf_set_str_slot,
-
0,
-
offsetof(ngx_core_conf_t, pid),
-
NULL },
-
-
{ ngx_string("lock_file"),
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
-
ngx_conf_set_str_slot,
-
0,
-
offsetof(ngx_core_conf_t, lock_file),
-
NULL },
-
-
{ ngx_string("worker_processes"),
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
-
ngx_conf_set_num_slot,
-
0,
-
offsetof(ngx_core_conf_t, worker_processes),
-
NULL },
-
-
/* ... 省略中间的定义 */
-
-
#if (NGX_THREADS)
-
-
{ ngx_string("worker_threads"),
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
-
ngx_conf_set_num_slot,
-
0,
-
offsetof(ngx_core_conf_t, worker_threads),
-
NULL },
-
-
{ ngx_string("thread_stack_size"),
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
-
ngx_conf_set_size_slot,
-
0,
-
offsetof(ngx_core_conf_t, thread_stack_size),
-
NULL },
-
-
#endif
-
-
ngx_null_command
-
}
3.2 open_files链表中的文件名何时初始化?
在初始化open_files链表之后遍历该链表并打开文件之前,并未看到向open_files链表中写入文件名。那么,何时写入open_files链表的?
——在ngx_conf_open_file函数中写入。
具体请参考源代码。打开文件后,open_files链表就保存了ngx_open_file_t结构的数据,具体请参考该结构定义。
4.小结
本文主要分析ngx_cycle的初始化,后文继续分析其中调用的CORE模块的callback和配置文件解析等。
Appendix: ngx_init_cycle()代码
省略,可自行研究。
阅读(1453) | 评论(0) | 转发(0) |