Nginx源码初探之数据结构 - 链接数据结构

       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然后创建连接对象,然后进行读写事件处理,最后客户端或者服务端断掉连接。

发布了15 篇原创文章 · 获赞 1 · 访问量 347

猜你喜欢

转载自blog.csdn.net/mlydaemon/article/details/103958724
今日推荐