最近在開始看nginx的事件模塊,經常看到ngx_cycle_t、ngx_connection_t和ngx_listening_t這三個結構體,剛開始沒在意,看到了就重新上網變量的意思,後來覺得不弄懂這三個結構體或者不清出其中變量的意義實在是無法看下去,因爲有很多函數都涉及這三個結構體。因爲ngx_listening_t存儲監聽有關的信息,ngx_connection_t存儲連接有關的信息和讀寫事件,而ngx_cycle_t這個結構體幾乎就是核心結構體,在nginx初始化時這個結構體存儲了許多東西,而且它有個初始化的函數:ngx_init_cycle,這個函數的代碼有700多行。可見這個結構體有多種要。於是就花了半天來找這幾個結構體裏面成員的意思,方便查閱,由於這些資料是來自課本和互聯網難免有錯誤,以後還會修改和繼續添加其他常用的結構體。
http://blog.csdn.net/xiaoliangsky/article/details/398310351ngx_listening_t
在core/ngx_connection.h中
struct ngx_listening_s {
ngx_socket_t fd;//套接字句柄
struct sockaddr *sockaddr;//監聽sockaddr地址
socklen_t socklen; /*sockaddr地址長度 size of sockaddr */
size_t addr_text_max_len;//存儲ip地址的字符串addr_text最大長度
ngx_str_t addr_text;//以字符串形式存儲ip地址
//套接字類型。types是SOCK_STREAM時,表示是tcp
int type;
//TCP實現監聽時的backlog隊列,它表示允許正在通過三次握手建立tcp連接但還沒有任何進程開始處理的連接最大個數
int backlog;
int rcvbuf;//套接字接收緩衝區大小
int sndbuf;//套接字發送緩衝區大小
/* handler of accepted connection */
ngx_connection_handler_pt handler;//當新的tcp連接成功建立後的處理方法
//目前主要用於HTTP或者mail等模塊,用於保存當前監聽端口對應着的所有主機名
void *servers; /* array of ngx_http_in_addr_t, for example */
ngx_log_t log;//日誌
ngx_log_t *logp;//日誌指針
size_t pool_size;//如果爲新的tcp連接創建內存池,則內存池的初始大小應該是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結構,用於組成單鏈表
ngx_listening_t *previous;
ngx_connection_t *connection;//當前監聽句柄對應的ngx_connection_t結構體
unsigned open:1;//爲1表示監聽句柄有效,爲0表示正常關閉
unsigned remain:1;//爲1表示不關閉原先打開的監聽端口,爲0表示關閉曾經打開的監聽端口
unsigned ignore:1;//爲1表示跳過設置當前ngx_listening_t結構體中的套接字,爲0時正常初始化套接字
unsigned bound:1; /* already bound */
unsigned inherited:1; /* inherited from previous process */
unsigned nonblocking_accept:1;
unsigned listen:1;//爲1表示當前結構體對應的套接字已經監聽
unsigned nonblocking:1;
unsigned shared:1; /* shared between threads or processes */
unsigned addr_ntop:1;//爲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
#if (NGX_HAVE_SETFIB)
int setfib;
#endif
};
2ngx_connction_t
在core/ngx_connection.h中
struct ngx_connection_s {
//連接未使用時,data用於充當連接池中空閒鏈表中的next指針。連接使用時由模塊而定,HTTP中,data指向ngx_http_request_t
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監聽端口的事件建立
ngx_listening_t *listening;
off_t sent;//這個連接上已發送的字節數
ngx_log_t *log;//日誌對象
/*內存池。一般在accept一個新的連接時,會創建一個內存池,而在這個連接結束時會銷燬內存池。內存池大小是由上面listening成員的pool_size決定的*/
ngx_pool_t *pool;
struct sockaddr *sockaddr;//連接客戶端的sockaddr
socklen_t socklen;//sockaddr結構體的長度
ngx_str_t addr_text;//連接客戶段字符串形式的IP地址
#if (NGX_SSL)
ngx_ssl_connection_t *ssl;
#endif
//本機監聽端口對應的sockaddr結構體,實際上就是listening監聽對象的sockaddr成員
struct sockaddr *local_sockaddr;
ngx_buf_t *buffer;//用戶接受、緩存客戶端發來的字符流,buffer是由連接內存池分配的,大小自由決定
/*用來將當前連接以雙向鏈表元素的形式添加到ngx_cycle_t核心結構體的reuseable_connection_queue雙向鏈表中,表示可以重用的連接*/
ngx_queue_t queue;
/*連接使用次數。ngx_connection_t結構體每次建立一條來自客戶端的連接,或者主動向後端服務器發起連接時,number都會加1*/
ngx_atomic_uint_t number;
ngx_uint_t requests;//處理的請求次數
//緩存中的業務類型。
unsigned buffered:8;
//本連接的日誌級別,佔用3位,取值範圍爲0~7,但實際只定義了5個值,由ngx_connection_log_error_e枚舉表示。
unsigned log_error:3; /* ngx_connection_log_error_e */
unsigned single_connection:1;//爲1時表示獨立的連接,爲0表示依靠其他連接行爲而建立起來的非獨立連接
unsigned unexpected_eof:1;//爲1表示不期待字符流結束
unsigned timedout:1;//爲1表示連接已經超時
unsigned error:1;//爲1表示連接處理過程中出現錯誤
unsigned destroyed:1;//爲1表示連接已經銷燬
unsigned idle:1;//爲1表示連接處於空閒狀態,如keepalive兩次請求中間的狀態
unsigned reusable:1;//爲1表示連接可重用,與上面的queue字段對應使用
unsigned close:1;//爲1表示連接關閉
unsigned sendfile:1;//爲1表示正在將文件中的數據發往連接的另一端
/*爲1表示只有連接套接字對應的發送緩衝區必須滿足最低設置的大小閥值時,事件驅動模塊纔會分發該事件。這與ngx_handle_write_event方法中的lowat參數是對應的*/
unsigned sndlowat:1;
unsigned tcp_nodelay:2; /* ngx_connection_tcp_nodelay_e */
unsigned tcp_nopush:2; /* ngx_connection_tcp_nopush_e */
#if (NGX_HAVE_IOCP)
unsigned accept_context_updated:1;
#endif
#if (NGX_HAVE_AIO_SENDFILE)
unsigned aio_sendfile:1;
ngx_buf_t *busy_sendfile;
#endif
#if (NGX_THREADS)
ngx_atomic_t lock;
#endif
};
3ngx_cycle_t
在core/ngx_cycle.h中
struct ngx_cycle_s {
/*保存着所有模塊存儲配置項的結構體指針,它首先是一個數組,每個數組成員又是一個指針,這個指針指向另一個存儲着指針的數組*/
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;
/*調用ngx_init_cycle方法後,會用new_log的地址覆蓋上面的log指針*/
ngx_log_t new_log;
//fiels保存所有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啓動失敗。
ngx_array_t pathes;
//保存Nginx已經打開的所有文件(ngx_open_file_t結構體)的單鏈表。
ngx_list_t open_files;
//單鏈表存儲ngx_shm_zone_t,每個元素表示一塊共享內存。
ngx_list_t shared_memory;
//表示當前進程中所有連接對象的總數,與下面的connections成員配合使用
ngx_uint_t connection_n;
//表示files數組中ngx_connection_t指針的總數
ngx_uint_t files_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_clcle對象就會保存這個前期的ngx_clcle_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;
};
4ngx_conf_t
在core/ngx_conf_file.h
struct ngx_conf_s {
char *name;//存放當前解析到的指令
ngx_array_t *args;//存放包含該指令的所有參數
ngx_cycle_t *cycle;//這個是核心的結構體,參看ngx_cycle.h文件
ngx_pool_t *pool;//內存池
ngx_pool_t *temp_pool;//用於存放解析配置文件的臨時內存池,解析後會釋放
ngx_conf_file_t *conf_file;//ngx_conf_file_t結構體的指針
ngx_log_t *log;//
void *ctx;//描述指令的上下文
ngx_uint_t module_type;//支持指令的模塊類型
ngx_uint_t cmd_type;//指令的類型
ngx_conf_handler_pt handler;//指令自定義的處理函數
char *handler_conf;//自定義處理函數需要的相關配置
};