ngx_event_t事件和ngx_connection_t連接是處理TCP連接的基礎數據結構。Nginx處理請求連接有三個主要的數據結構,ngx_cycle_t全局變量結構體,ngx_connection_t網絡鏈接結構體,ngx_listening_t網絡監聽結構體。這三個結構體是nginx事件模塊的核心結構體。ngx_connection_t存儲網絡鏈接和讀寫事件,ngx_listening_t存儲監聽信息主要是端口。
1.ngx_listening_s數據結構
typedef struct ngx_listening_s ngx_listening_t;
struct ngx_listening_s {
ngx_socket_t fd;/*socket句柄*/
struct sockaddr *sockaddr;/*socket地址*/
socklen_t socklen; /*sockaddr地址的長度 size of sockaddr */
size_t addr_text_max_len;
ngx_str_t addr_text;
int type;/*socket鏈接類型*/
int backlog;
int rcvbuf;/*接收work進程緩衝區大小*/
int sndbuf;/*發送work進程緩衝區大小*/
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
int keepidle;
int keepintvl;
int keepcnt;
#endif
/* handler of accepted connection */
ngx_connection_handler_pt handler;/* 接受到新的請求後的處理方法*/
void *servers; /* 監聽器對應的所有主機名*/
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;/*監聽器所監聽的連接池指針*/
ngx_rbtree_t rbtree;
ngx_rbtree_node_t sentinel;
ngx_uint_t worker;/*工作進程的數量*/
unsigned open:1;/*socket狀態,1表示開啓,0表示關閉*/
unsigned remain:1;/*監聽端口狀態,1表示開啓,0表示關閉*/
unsigned ignore:1;/*鏈接管理,1表示忽略socket連接,0表示不忽略*/
unsigned bound:1; /* already bound */
unsigned inherited:1; /* i是否繼承於上一個進程 */
unsigned nonblocking_accept:1;
unsigned listen:1;/* 監聽狀態,1表示已經監聽*/
unsigned nonblocking:1;
unsigned shared:1; /* shared between threads or processes */
unsigned addr_ntop:1;
unsigned wildcard:1;
#if (NGX_HAVE_INET6)
unsigned ipv6only:1;
#endif
unsigned reuseport:1;
unsigned add_reuseport:1;
unsigned keepalive:2;
unsigned deferred_accept:1;
unsigned delete_deferred:1;
unsigned add_deferred:1;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
char *accept_filter;
#endif
#if (NGX_HAVE_SETFIB)
int setfib;
#endif
#if (NGX_HAVE_TCP_FASTOPEN)
int fastopen;
#endif
};
2.ngx_connection_s數據結構
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;
int type;
struct sockaddr *sockaddr;
socklen_t socklen;
ngx_str_t addr_text;
…………………………………………………………………………………………
#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
unsigned busy_count:2;
#endif
#if (NGX_THREADS || NGX_COMPAT)
ngx_thread_task_t *sendfile_task;
#endif
};
3.鏈接生命週期
ngx_connection_t是Nginx對tcp連接的封裝。我們可以從TCP的生命週期來考察ngx_connnection_t的生命週期,在這裏我將他分爲兩部分,一部分是連接環境的準備階段,另一個階段是connection的管理階段。
3.1準備階段
nginx在啓動時,會解析配置文件,得到需要監聽的端口和IP。然後Nginx在master進程中,初始化好socket連接,然後fork出多個work子進程,子進程之間會競爭客戶端的連接請求。
3.2connection的管理階段
work進程獲取到客戶端請求後,獲取socket然後創建連接對象,然後進行讀寫事件處理,最後客戶端或者服務端斷掉連接。