Nginx源碼初探之數據結構 - 鏈接數據結構

       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然後創建連接對象,然後進行讀寫事件處理,最後客戶端或者服務端斷掉連接。

 

發佈了27 篇原創文章 · 獲贊 1 · 訪問量 2231
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章