Nginx依赖的库如下:
[qxz@qiuxuezhong-test-dev001-sjhl tools]$ldd /usr/local/nginx/sbin/nginx
linux-vdso.so.1=> (0x00007fffbbfff000)
libpthread.so.0=> /lib64/libpthread.so.0 (0x0000003267c00000)
libcrypt.so.1=> /lib64/libcrypt.so.1 (0x0000003269800000)
libpcre.so.1=> /usr/local/lib/libpcre.so.1 (0x00002b23b7b4a000)
libcrypto.so.10=> /usr/lib64/libcrypto.so.10 (0x0000003e2b400000)
libz.so.1=> /lib64/libz.so.1 (0x0000003268000000)
libc.so.6=> /lib64/libc.so.6 (0x0000003267400000)
/lib64/ld-linux-x86-64.so.2(0x0000003267000000)
libfreebl3.so=> /usr/lib64/libfreebl3.so (0x0000003269c00000)
libdl.so.2=> /lib64/libdl.so.2 (0x0000003267800000)
ngx_cycle_s包含了内存池、连接池、文件等,因此属于资源的管理者,应该是pbrpc中的RpcServer
struct ngx_cycle_s {
void ****conf_ctx;
ngx_pool_t *pool;
ngx_log_t *log;
ngx_log_t new_log;
ngx_uint_t log_use_stderr; /* unsigned log_use_stderr:1; */
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 paths;
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;
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;
};
其中conf_ctx;为甚要用4级指针?
ngx_add_inherited_sockets函数中,查看了是否有环境变量NGINX,用于识别是否需要平滑升级。
Nginx注册模块是在main函数之前,
如下:
3 = 0
(gdb) watch ngx_max_module
Hardware watchpoint 2: ngx_max_module
(gdb) p ngx_modules[0]
$4 = (ngx_module_t *) 0x6806c0<ngx_core_module>
(gdb) p ngx_modules[1]
$5 = (ngx_module_t *) 0x680c60<ngx_errlog_module>
(gdb) p ngx_modules[2]
$6 = (ngx_module_t *) 0x6815c0<ngx_conf_module>
(gdb) p ngx_modules[4]
$7 = (ngx_module_t *) 0x681720<ngx_event_core_module>
(gdb) p ngx_modules[5]
$8 = (ngx_module_t *) 0x681e20<ngx_epoll_module>
(gdb) p ngx_modules[6]
$9 = (ngx_module_t *) 0x682060<ngx_regex_module>
(gdb) p ngx_modules[7]
$10 = (ngx_module_t *) 0x6821e0<ngx_http_module>
(gdb) p ngx_modules[8]
$11 = (ngx_module_t *) 0x6824c0<ngx_http_core_module>
(gdb) p ngx_modules[9]
$12 = (ngx_module_t *) 0x685ce0<ngx_http_log_module>
(gdb) p ngx_modules[11]
$13 = (ngx_module_t *) 0x6877a0<ngx_http_static_module>
(gdb) p ngx_modules[10]
$14 = (ngx_module_t *) 0x687000<ngx_http_upstream_module>
(gdb) p ngx_modules[12]
$15 = (ngx_module_t *) 0x689660<ngx_http_autoindex_module>
(gdb) p ngx_modules[13]
$16 = (ngx_module_t *) 0x6878c0<ngx_http_index_module>
(gdb) p ngx_modules[14]
$17 = (ngx_module_t *) 0x689860<ngx_http_auth_basic_module>
(gdb) p ngx_modules[1]
$18 = (ngx_module_t *) 0x680c60<ngx_errlog_module>
(gdb) p ngx_modules[15]
$19 = (ngx_module_t *) 0x689a40<ngx_http_access_module>
(gdb) p ngx_modules[16]
$20 = (ngx_module_t *) 0x689c20<ngx_http_limit_conn_module>
(gdb) p ngx_modules[17]
$21 = (ngx_module_t *) 0x689f60<ngx_http_limit_req_module>
(gdb) p ngx_modules[18]
$22 = (ngx_module_t *) 0x68a260<ngx_http_geo_module>
(gdb) p ngx_modules[19]
$23 = (ngx_module_t *) 0x68a3c0<ngx_http_map_module>
(gdb) p ngx_modules[20]
$24 = (ngx_module_t *) 0x68a5c0<ngx_http_split_clients_module>
(gdb) p ngx_modules[21]
$25 = (ngx_module_t *) 0x68a720<ngx_http_referer_module>
(gdb) p ngx_modules[22]
$26 = (ngx_module_t *) 0x68a920<ngx_http_rewrite_module>
(gdb) p ngx_modules[23]
$27 = (ngx_module_t *) 0x68bb00<ngx_http_proxy_module>
(gdb) p ngx_modules[24]
$28 = (ngx_module_t *) 0x68c940<ngx_http_fastcgi_module>
(gdb) p ngx_modules[25]
$29 = (ngx_module_t *) 0x68d580<ngx_http_uwsgi_module>
(gdb) p ngx_modules[26]
$30 = (ngx_module_t *) 0x68e140<ngx_http_scgi_module>
(gdb) p ngx_modules[27]
$31 = (ngx_module_t *) 0x68e340<ngx_http_memcached_module>
(gdb) p ngx_modules[28]
$32 = (ngx_module_t *) 0x68e720<ngx_http_empty_gif_module>
(gdb) p ngx_modules[29]
$33 = (ngx_module_t *) 0x68ea60<ngx_http_browser_module>
(gdb) p ngx_modules[30]
$34 = (ngx_module_t *) 0x68eca0<ngx_http_upstream_ip_hash_module>
(gdb) p ngx_modules[31]
$35 = (ngx_module_t *) 0x68ee00<ngx_http_upstream_least_conn_module>
(gdb) p ngx_modules[32]
$36 = (ngx_module_t *) 0x68efa0<ngx_http_upstream_keepalive_module>
(gdb) p ngx_modules[33]
$37 = (ngx_module_t *) 0x6858c0<ngx_http_write_filter_module>
(gdb) p ngx_modules[34]
$38 = (ngx_module_t *) 0x6857a0<ngx_http_header_filter_module>
(gdb) p ngx_modules[35]
$39 = (ngx_module_t *) 0x687a60<ngx_http_chunked_filter_module>
(gdb) p ngx_modules[36]
$40 = (ngx_module_t *) 0x687ca0<ngx_http_range_header_filter_module>
(gdb) p ngx_modules[37]
$41 = (ngx_module_t *) 0x6881e0<ngx_http_gzip_filter_module>
(gdb) p ngx_modules[50]
$42 = (ngx_module_t *) 0x326747a8a0<malloc>
(gdb) p ngx_modules[40]
$43 = (ngx_module_t *) 0x688ea0<ngx_http_charset_filter_module>
(gdb) p ngx_modules[45]
$44 = (ngx_module_t *) 0x688020<ngx_http_not_modified_filter_module>
(gdb) p ngx_modules[48]
$45 = (ngx_module_t *) 0x7fffffffe4f8
(gdb) p ngx_modules[47]
$46 = (ngx_module_t *) 0x0
这么多模块是怎么初始化的?
是在make命令自动生成的文件ngx_modules.c中
ngx_module_t *ngx_modules[] = { &ngx_core_module, &ngx_errlog_module, &ngx_conf_module, &ngx_events_module, &ngx_event_core_module, &ngx_epoll_module, &ngx_regex_module, &ngx_http_module, &ngx_http_core_module, &ngx_http_log_module, &ngx_http_upstream_module, &ngx_http_static_module, &ngx_http_autoindex_module, &ngx_http_index_module, &ngx_http_auth_basic_module, &ngx_http_access_module, &ngx_http_limit_conn_module, &ngx_http_limit_req_module, &ngx_http_geo_module, &ngx_http_map_module, &ngx_http_split_clients_module, &ngx_http_referer_module, &ngx_http_rewrite_module, &ngx_http_proxy_module, &ngx_http_fastcgi_module, &ngx_http_uwsgi_module, &ngx_http_scgi_module, &ngx_http_memcached_module, &ngx_http_empty_gif_module, &ngx_http_browser_module, &ngx_http_upstream_ip_hash_module, &ngx_http_upstream_least_conn_module, &ngx_http_upstream_keepalive_module, &ngx_http_write_filter_module, &ngx_http_header_filter_module, &ngx_http_chunked_filter_module, &ngx_http_range_header_filter_module, &ngx_http_gzip_filter_module, &ngx_http_postpone_filter_module, &ngx_http_ssi_filter_module, &ngx_http_charset_filter_module, &ngx_http_userid_filter_module, &ngx_http_headers_filter_module, &ngx_http_copy_filter_module, &ngx_http_range_body_filter_module, &ngx_http_not_modified_filter_module, NULL }; |
nginx模块化
ngx_listening_s相当于pbrpc中的acceptor,用于监听网络连接请求,创建新的连接。
配置模块相当于配置文件解析模块,在pbrpc中,配置文件直接使用proto定义的。配置模块的解析函数:ngx_conf_parse,其中会依据配置的命令,调用相应cmd中的handler函数。
模块的定义如下:
struct ngx_module_s { ngx_uint_t ctx_index; ngx_uint_t index;
ngx_uint_t spare0; ngx_uint_t spare1; ngx_uint_t spare2; ngx_uint_t spare3;
ngx_uint_t version;
void *ctx; ngx_command_t *commands; ngx_uint_t type;
ngx_int_t (*init_master)(ngx_log_t *log);
ngx_int_t (*init_module)(ngx_cycle_t *cycle);
ngx_int_t (*init_process)(ngx_cycle_t *cycle); ngx_int_t (*init_thread)(ngx_cycle_t *cycle); void (*exit_thread)(ngx_cycle_t *cycle); void (*exit_process)(ngx_cycle_t *cycle);
void (*exit_master)(ngx_cycle_t *cycle);
uintptr_t spare_hook0; uintptr_t spare_hook1; uintptr_t spare_hook2; uintptr_t spare_hook3; uintptr_t spare_hook4; uintptr_t spare_hook5; uintptr_t spare_hook6; uintptr_t spare_hook7; }; |
|
在ngx_spawn_process
中使用了folk的系统调用,子进程返回后调用了ngx_worker_process_cycle。
ngx_process_events_and_timers是事件处理函数。
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; #if (NGX_HAVE_KEEPALIVE_TUNABLE) int keepidle; int keepintvl; int keepcnt; #endif
/* 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:1; #endif unsigned keepalive:2;
#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 #if (NGX_HAVE_SETFIB) int setfib; #endif
#if (NGX_HAVE_TCP_FASTOPEN) int fastopen; #endif
};
|
为什么需要性能链表?多个监听端口
Ngx_connection_s相当于Tcp_connection
struct ngx_connection_s { void *data; ngx_event_t *read; ngx_event_t *write;
ngx_socket_t fd;
ngx_recv_pt recv; ngx_send_pt send; ngx_recv_chain_pt recv_chain; ngx_send_chain_pt send_chain;
ngx_listening_t *listening;
off_t sent;
ngx_log_t *log;
ngx_pool_t *pool;
struct sockaddr *sockaddr; socklen_t socklen; ngx_str_t addr_text;
ngx_str_t proxy_protocol_addr;
#if (NGX_SSL) ngx_ssl_connection_t *ssl; #endif
struct sockaddr *local_sockaddr; socklen_t local_socklen;
ngx_buf_t *buffer;
ngx_queue_t queue;
ngx_atomic_uint_t number;
ngx_uint_t requests;
unsigned buffered:8;
unsigned log_error:3; /* ngx_connection_log_error_e */
unsigned unexpected_eof:1; unsigned timedout:1; unsigned error:1; unsigned destroyed:1;
unsigned idle:1; unsigned reusable:1; unsigned close:1;
unsigned sendfile:1; unsigned sndlowat:1; unsigned tcp_nodelay:2; /* ngx_connection_tcp_nodelay_e */ unsigned tcp_nopush:2; /* ngx_connection_tcp_nopush_e */
unsigned need_last_buf:1;
#if (NGX_HAVE_IOCP) unsigned accept_context_updated:1; #endif
#if (NGX_HAVE_AIO_SENDFILE) unsigned aio_sendfile:1; unsigned busy_count:2; ngx_buf_t *busy_sendfile; #endif
#if (NGX_THREADS) ngx_atomic_t lock; #endif };
|
参考:
http://blog.youkuaiyun.com/livelylittlefish/article/details/6571497