nginx 超时机制

nginx,读法eng事件机制尤如nginx的心脏一般
摘要由CSDN通过智能技术生成

nginx,读法engine X,事件机制尤如nginx的引擎了.

服务器无非就是,监听、请求、接受、响应,包括超时处理.nginx虽然设计的很复杂,但是刨根究底,无非也是这些东西.

  • 连接和事件的定义

只要能产生fd的(不管是监听,还是请求),都是连接,一个fd对应一个连接connection。 
每个连接有两个事件(event),可以读(read)和写(write)结构体为: 

struct ngx_connection_s {
    /*
    连接未使用时,data成员用于充当连接池中空闲连接链表中的next指针。当连接被使用时,data的意义由使用它的nginx模块而定,
    如在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_chain_t链表为参数来接收网络字符流的方法
    ngx_recv_chain_pt   recv_chain;
    // 以ngx_chain_t链表为参数来发送网络字符流的方法
    ngx_send_chain_pt   send_chain;

    // 这个连接对应的ngx_listening_t监听对象,此连接由listening 监听端口的事件建立
    ngx_listening_t    *listening;

    // 这个连接上已经发送出去的字节数
    off_t               sent;

    // 可以记录日志的ngx_log_t对象
    ngx_log_t          *log;

    /*
    内存池,一般在accept一个新连接时,会创建一个内存池,而在这个连接结束时会销毁内存池。
    */
    ngx_pool_t         *pool;

    //连接客户端的socketaddr结构体
    struct sockaddr    *sockaddr;
    // socketaddr结构体的长度
    socklen_t           socklen;
    // 连接客户端字符串形式的IP地址
    ngx_str_t           addr_text;

#if (NGX_SSL)
    ngx_ssl_connection_t  *ssl;
#endif

    // 本机的监听端口对应的socketaddr结构体,也就是listening监听对象中的sockaddr成员
    struct sockaddr    *local_sockaddr;

    /* 
    用于接收、缓存客户端发来的字符流,每个事件消费模块可自由决定从连接池中分配多大的空间给 buffer这个接收缓存字段。
    例如,在HTTP模块中,它的大小决定于client_header_buffer_size配置项
    */ 
    ngx_buf_t          *buffer;

    /*
    该字段用于将当前连接以双向链表元素的形式添加到ngx_cycle_t核心结构体的reusable_connections_queue双向链表中,表示可重用的连接
    */
    ngx_queue_t         queue;

    /*
    连接使用次数。ngx_connection_t结构体每次建立一条来自客户端的连接,或者用于主动向后端服务器发起连接时 (ngx_peer_connection_t也使用它)
    number都会加1
    */
    ngx_atomic_uint_t   number;

    // 处理的请求次数
    ngx_uint_t          requests;

    /*
    缓存中的业务类型。任何事件消费模块都可以自定义需要的标志位。
    这个buffered字段有8位,最多可以同时表示8个不同的业务。第三方模块在自定义buffered标志位时注意不要与可能使用的模块定义的标志位冲突。
    */
    unsigned            buffered:8;

    /*
    本连接记录日志时的级别,它占用了3位,取值范围是0~7,但实际上目前只定义了5个值,由ngx_connection_log_error_e枚举表示,如下:
    typedef enum{
        NGX_ERROR_ALERT = 0,
        NGX_ERROR_ERR,
        NGX_ERROR_INFO,
        NGX_ERROR_IGNORE_ECONNRESET,
        NGX_ERROR_IGNORE_EINVAL,
    } ngx_connection_log_error_e;
    */
    unsigned            log_error:3;     /* ngx_connection_log_error_e */

    /*
    标志位,为1表示独立的连接,如从客户端发起的连接;
    为0表示依靠其他连接的行为而建立起来的非独立连接,如使用upstream机制向后端服务器建立起来的连接
    */
    unsigned            single_connection:1;
    // 标志位,为1表示不期待字符流结束,目前无意义
    unsigned            unexpected_eof:1;
    // 标志位,为1表示连接已超时
    unsigned            timedout:1;
    // 标志位,为1表示连接处理过程中出现错误
    unsigned            error:1;
    // 标志位,为1表示连接已经销毁。这里的连接指的是TCP连接,而不是ngx_connection_t结构体。
    // 当destroy为1时,ngx_connection_t结构体仍然存在,但其对应的套接字,内存池已经不可用。
    unsigned            destroyed:1;

    // 标志位,为1表示连接处于空闲状态,如keepalive请求中两次请求之间的状态
    unsigned            idle:1;
    // 标志位,为1表示连接可重用,它与上面的queue字段是对应使用的
    unsigned            reusable:1;
    // 标志位,为1表示连接关闭
    unsigned            close:1;

    // 标志位,为1表示正在将文件中的数据发往连接的另一端
    unsigned            sendfile:1;
    /*
    标志位,如果为1, 则表示只有在连接套接字对应的发送缓冲区必须满足最低设置的大小阀值,事件驱动模型才会分发该事件。
    */ 
    unsigned            sndlowat:1;
    // 标志位,表示如何使用TCP的nodelay特性。它的取值范围是ngx_connection_tcp_nodelay_e
    unsigned            tcp_nodelay:2;   /* ngx_connection_tcp_nodelay_e */
    // 标志位,表示如何使用TCP的nopush特性,它的取值范围是ngx_connection_tcp_nopush_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)
    // 标志位,为1时表示使用异步I/O的方式将磁盘上文件发送给网络连接的另一端
    unsigned            aio_sendfile:1;
    // 使用异步 I/O 方式发送的文件,busy_sendfile缓冲区保存待发送文件的信息
    ngx_buf_t          *busy_sendfile;
#endif

#if (NGX_THREADS)
    ngx_atomic_t        lock;
#endif
};


struct ngx_event_s {
    // 事件相关的对象。通常data都是指向ngx_connection_t连接对象。开启文件异步I/O时,它可能会指向ngx_event_aio_t结构体
    void            *data;

    /*
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值