nginx的事件处理函数

 

1. 数据结构

connection中有read/write两种事件

struct ngx_connection_s {
    void               *data;
    ngx_event_t        *read;
    ngx_event_t        *write;
    ...
}
struct ngx_event_s {
...
    ngx_event_handler_pt  handler;
...
}

 

2. 事件handler调用时机

epoll触发。是否与定时器有关系?

 

3. request 

 在系统 ngx_http_init_connection()中初始化如下:

rev = c->read;
rev->handler = ngx_http_wait_request_handler;
c->write->handler = ngx_http_empty_handler;

然后ngx_wait_request_handler接受到数据,然后创建request,然后修改read hander如下

rev->handler = ngx_http_process_request_line;
ngx_http_process_request_line(rev); 

处理完request line之后,设置read handler如下

rev->handler = ngx_http_process_request_headers; 
ngx_http_process_request_headers(rev);

在处理完header之后,修改read/write handler如下

c->read->handler = ngx_http_request_handler;
c->write->handler = ngx_http_request_handler;

在处理完request之后, ngx_http_set_keepalive(r)函数会设置

wev = c->write;
wev->handler = ngx_http_empty_handler;
rev->handler = ngx_http_keepalive_handler; 

以后再讨论r->read_event_hander和r->write_event_handler;

 

4. TLS

4.2 普通场景

在ngx_http_init_connection之中,设置read handler为ngx_http_ssl_handshake,进入握手流程。

    if (sscf->enable || hc->addr_conf->ssl) {
        hc->ssl = 1; 
        c->log->action = "SSL handshaking";
        rev->handler = ngx_http_ssl_handshake;
    }    

 然后设置read/write的handler如下

c->read->handler = ngx_ssl_handshake_handler;
c->write->handler = ngx_ssl_handshake_handler;

 

当握手成功后,修改handler如下

        c->read->handler = ngx_http_wait_request_handler;
        /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;

后面就是处理request的流程了,转第3节

当需要关闭连接的时候,视情况设置handler如下


c->read->handler = ngx_ssl_shutdown_handler;
c->write->handler = ngx_ssl_shutdown_handler;

 

4.3 early data

TODO

if (c->ssl->saved_read_handler == NULL) {
    c->ssl->saved_read_handler = c->read->handler;
    c->read->handler = ngx_ssl_read_handler;
}

 

5. HTTP2

5.1 真实连接

在ngx_http_init_connection中设置ngx_http_v2_init,或者在tls握手之后调用ngx_http_v2_init

rev->handler = ngx_http_v2_read_handler;
c->write->handler = ngx_http_v2_write_handler; 

处理完stream后,

c->write->handler = ngx_http_empty_handler;
c->read->handler = ngx_http_v2_idle_handler;

然后,当有新的stream来时,在ngx_http_v2_idle_handler中设置如下,准备接收新的stream:

ngx_http_v2_idle_handler()
{
...
    c->write->handler = ngx_http_v2_write_handler;
    rev->handler = ngx_http_v2_read_handler;
...
}

在准备关掉连接的时候,设置read/write的handler如下:

ngx_http_v2_finalize_connection()
{
...
    c->read->handler = ngx_http_empty_handler;
    c->write->handler = ngx_http_empty_handler;
...
}

 

5.2 fake connection是怎么处理的呢?

 分配fc/read/write,然后初始化如下:

ngx_http_v2_create_stream()
{
...
    rev->handler = ngx_http_v2_close_stream_handler;
    ngx_memcpy(wev, rev, sizeof(ngx_event_t));
    fc->read = rev;
    fc->write = wev;
...
}

然后在ngx_http_v2_run_request()调用ngx_http_process_request(r),进而把read/write的handler设置为:

c->read->handler = ngx_http_request_handler;
c->write->handler = ngx_http_request_handler; 

进而进入了第3节。

当stream结束时,如果此时准备删除连接,则设置handler为:

ngx_http_v2_close_stream() 
{
...
    //等待stream数据传输
    if (stream->queued) {
        fc->write->handler = ngx_http_v2_close_stream_handler;
        fc->read->handler = ngx_http_empty_handler;
        return;
    }

    //真实连接
       ev->handler = ngx_http_v2_handle_connection_handler; 
...
}

 

在push数据的时候

ngx_http_v2_push_stream()
{
...
stream = ngx_http_v2_create_stream(h2c, 1);
fc->write->handler = ngx_http_v2_run_request_handler;
...
}

fc的read/write引用真实连接的read/write。

 

6. upstream

 

ngx_http_upstream_connect函数初始化upstream的connection的handler为

c->write->handler = ngx_http_upstream_handler;
c->read->handler = ngx_http_upstream_handler;

当处理完请求后设置为

c->write->handler = ngx_http_upstream_keepalive_dummy_handler; 
c->read->handler = ngx_http_upstream_keepalive_close_handler;

 

总结

epoll触发读写事件,从而调用到这些handler,驱动了nginx的处理流程。这些处理函数都很简略,以后再分析这些handler进一步调用那些函数。

 

2019.10.27

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值