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