序
本文主要研究一下nginx的keepalive相关参数
keepalive_timeout
Syntax: keepalive_timeout timeout [header_timeout];
Default:
keepalive_timeout 75s;
Context: http, server, location
默认是75s,客户端的一个keep-alive连接在服务端保持open的时间,为0表示禁用keep-alive,可选指定header_timeout,若有指定则response header会有
Keep-Alive: timeout=time
,该header能被Mozilla和Konqueror浏览器识别,MSIE浏览器大概在60s会关闭keep-alive连接
keepalive_requests
Syntax: keepalive_requests number;
Default:
keepalive_requests 1000;
Context: http, server, location
keepalive_requests用于指定一个keep-alive连接最大处理的请求数,超过此值则连接被关闭
ngx_http_core_module
nginx/src/http/ngx_http_core_module.c
void
ngx_http_update_location_config(ngx_http_request_t *r)
{ngx_http_core_loc_conf_t *clcf;clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);if (r->method & clcf->limit_except) {r->loc_conf = clcf->limit_except_loc_conf;clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);}if (r == r->main) {ngx_set_connection_log(r->connection, clcf->error_log);}if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {r->connection->sendfile = 1;} else {r->connection->sendfile = 0;}if (clcf->client_body_in_file_only) {r->request_body_in_file_only = 1;r->request_body_in_persistent_file = 1;r->request_body_in_clean_file =clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;r->request_body_file_log_level = NGX_LOG_NOTICE;} else {r->request_body_file_log_level = NGX_LOG_WARN;}r->request_body_in_single_buf = clcf->client_body_in_single_buffer;if (r->keepalive) {if (clcf->keepalive_timeout == 0) {r->keepalive = 0;} else if (r->connection->requests >= clcf->keepalive_requests) {r->keepalive = 0;} else if (ngx_current_msec - r->connection->start_time> clcf->keepalive_time){r->keepalive = 0;} else if (r->headers_in.msie6&& r->method == NGX_HTTP_POST&& (clcf->keepalive_disable& NGX_HTTP_KEEPALIVE_DISABLE_MSIE6)){/** MSIE may wait for some time if an response for* a POST request was sent over a keepalive connection*/r->keepalive = 0;} else if (r->headers_in.safari&& (clcf->keepalive_disable& NGX_HTTP_KEEPALIVE_DISABLE_SAFARI)){/** Safari may send a POST request to a closed keepalive* connection and may stall for some time, see* https://bugs.webkit.org/show_bug.cgi?id=5760*/r->keepalive = 0;}}if (!clcf->tcp_nopush) {/* disable TCP_NOPUSH/TCP_CORK use */r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;}if (clcf->handler) {r->content_handler = clcf->handler;}
}
ngx_http_core_module的ngx_http_update_location_config(ngx_http_request_t *r)方法在keepalive为true时,若connection的requests的requests大于等于配置的keepalive_requests,则设置keepalive为0;若ngx_current_msec减去connection的start_time等于keepalive_time则设置keepalive为0
ngx_http_header_filter
nginx/src/http/ngx_http_header_filter_module.c
static ngx_int_t
ngx_http_header_filter(ngx_http_request_t *r)
{u_char *p;size_t len;ngx_str_t host, *status_line;ngx_buf_t *b;ngx_uint_t status, i, port;ngx_chain_t out;ngx_list_part_t *part;ngx_table_elt_t *header;ngx_connection_t *c;ngx_http_core_loc_conf_t *clcf;ngx_http_core_srv_conf_t *cscf;u_char addr[NGX_SOCKADDR_STRLEN];if (r->header_sent) {return NGX_OK;}r->header_sent = 1;if (r != r->main) {return NGX_OK;}//......if (r->keepalive && (ngx_terminate || ngx_exiting)) {r->keepalive = 0;}//......if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {len += sizeof("Connection: upgrade" CRLF) - 1;} else if (r->keepalive) {len += sizeof("Connection: keep-alive" CRLF) - 1;/** MSIE and Opera ignore the "Keep-Alive: timeout=<N>" header.* MSIE keeps the connection alive for about 60-65 seconds.* Opera keeps the connection alive very long.* Mozilla keeps the connection alive for N plus about 1-10 seconds.* Konqueror keeps the connection alive for about N seconds.*/if (clcf->keepalive_header) {len += sizeof("Keep-Alive: timeout=") - 1 + NGX_TIME_T_LEN + 2;}} else {len += sizeof("Connection: close" CRLF) - 1;}//...... if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {b->last = ngx_cpymem(b->last, "Connection: upgrade" CRLF,sizeof("Connection: upgrade" CRLF) - 1);} else if (r->keepalive) {b->last = ngx_cpymem(b->last, "Connection: keep-alive" CRLF,sizeof("Connection: keep-alive" CRLF) - 1);if (clcf->keepalive_header) {b->last = ngx_sprintf(b->last, "Keep-Alive: timeout=%T" CRLF,clcf->keepalive_header);}} else {b->last = ngx_cpymem(b->last, "Connection: close" CRLF,sizeof("Connection: close" CRLF) - 1);}
}
ngx_http_header_filter_module的ngx_http_header_filter方法,在keepalive为1时会添加
Connection: keep-alive
,若开启keepalive_header,则添加Keep-Alive: timeout=%T"
;若keepalive为0时,则添加Connection: close
到response的header
小结
nginx提供了keepalive_timeout(一个keep-alive连接在服务端保持open的时间
)及keepalive_requests(一个keep-alive连接最大处理的请求数
)参数,其中ngx_http_core_module的ngx_http_update_location_config(ngx_http_request_t *r)方法在keepalive为true时,若connection的requests的requests大于等于配置的keepalive_requests,则设置keepalive为0;若ngx_current_msec减去connection的start_time等于keepalive_time则设置keepalive为0;而ngx_http_header_filter_module的ngx_http_header_filter方法,在keepalive为1时会添加Connection: keep-alive
,若开启keepalive_header,则添加Keep-Alive: timeout=%T"
;若keepalive为0时,则添加Connection: close
到response的header。
doc
- keepalive_timeout