Today I got the sequence of the initialization of the nginx. I found the way to inherited sockets from a parent process. Due to vary the different OS nginx past the inherited sockets between processes by environment variables. I think the environment variables like as follow.
NGINX=111:222:333:... or NGINX=111;222;333;...
The following is the part two of my notes.
三、Nginx启动处理
1. 从main()函数开始,进行了一系列的初始化处理工作。下面将分别介绍,对于不是很重要或是很好理解力的部分可能不作详细说明。
a) 首先是从命令行获取参数,打印参数的用法说明。
b) ngx_time_init()函数,获取当前系统的日期和时间。Nginx中定义了三个全局ngx_str_t变量,ngx_cached_err_log_time、ngx_cached_http_time、ngx_cached_http_log_time分别用来表示error.log中的时间格式,http协议中的时间格式,和accesse.log中的时间格式。另外,nginx中还分别定义了ngx_str_t 类型cached_err_log_time[NGX_TIME_SLOTS],cached_http_time[NGX_TIME_SLOTS],cached_http_log_time[NGX_TIME_SLOTS]用来缓存系统的时间。还有static ngx_time_t cached_time[NGX_TIME_SLOTS]。
这些数组的长度为64。这此缓存数极组有什么用处,还不知道。
在函数最后,调用ngx_time_update()。
c) ngx_time_update()函数,通过ngx_gettimeofday()取得当前的毫秒数,其后逻辑比较简单,只是根据获取的毫秒数通过一些系统调用获取年,月,日,时,分,秒以及按不同时区进行的转换。
d) 注意,在ngx_time_update()函数后部使用了一个ngx_memory_barrier()。这是个宏。对不同的编译器不同的环境有不同的定义。关于x86和gcc的定义如下:
/*
* on x86 the write operations go in a program order, so we need only
* to disable the gcc reorder optimizations
*/
#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
2. 用ngx_getpid()获取nginx的pid。
3. 如果宏NGX_OPENSSL定义了,在ngx_ssl_init()函数中载入open ssl的库。
4. 随后在全局的ngx_cycle变量中,创建内存池,大小为1024。
5. ngx_save_argv()函数则是将从main()函数传入的参数表保存到nginx的全局变量ngx_argc,ngx_argv[],ngx_os_argv[],ngx_os_environ中。
6. ngx_process_options()函数中取得当前程序所在的工作目录,并且创建相应的config文件。获取config文件的全路径。
7. ngx_crc32_table_init()函数中初始化用于crc32循环冗余校验的数据表。
8. ngx_add_inherited_sockets()函数中,继承父进程中的socket。继承方法是通过取得”NGINX”这个环境变量的值,该值是个由”:”或”;”作为分隔符的列表,列表是表示socket的文件描述符。Nginx将继承的socket压入一个堆栈中,然后置变量ngx_inherited为1,表示已经取得要继承的socket。
struct ngx_listening_s {
ngx_socket_t fd;
struct sockaddr *sockaddr;
socklen_t socklen; /* size of sockaddr */
size_t addr_text_max_len;
ngx_str_t addr_text;
int type;
int backlog;
int rcvbuf;
int sndbuf;
/* handler of accepted connection */
ngx_connection_handler_pt handler;
void *servers; /* array of ngx_http_in_addr_t, for example */
ngx_log_t log;
ngx_log_t *logp;
size_t pool_size;
/* should be here because of the AcceptEx() preread */
size_t post_accept_buffer_size;
/* should be here because of the deferred accept */
ngx_msec_t post_accept_timeout;
ngx_listening_t *previous;
ngx_connection_t *connection;
unsigned open:1;
unsigned remain:1;
unsigned ignore:1;
unsigned bound:1; /* already bound */
unsigned inherited:1; /* inherited from previous process */
unsigned nonblocking_accept:1;
unsigned listen:1;
unsigned nonblocking:1;
unsigned shared:1; /* shared between threads or processes */
unsigned addr_ntop:1;
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
unsigned ipv6only:2;
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT)
unsigned deferred_accept:1;
unsigned delete_deferred:1;
unsigned add_deferred:1;
#ifdef SO_ACCEPTFILTER
char *accept_filter;
#endif
#endif
};