当前位置: 首页 > 工具软件 > ng-katex > 使用案例 >

nginx学习十 ngx_cycle_t 、ngx_connection_t 和ngx_listening_t

穆文斌
2023-12-01

最近在开始看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;//自定义处理函数需要的相关配置
};


 类似资料: