ngx_http_finalize_connection

发布时间:2026/7/27 18:48:26
ngx_http_finalize_connection 1 定义ngx_http_finalize_connection函数定义在src/http/ngx_http_request.cstaticvoidngx_http_finalize_connection(ngx_http_request_t*r){ngx_http_core_loc_conf_t*clcf;#if(NGX_HTTP_V2)if(r-stream){ngx_http_close_request(r,0);return;}#endifclcfngx_http_get_module_loc_conf(r,ngx_http_core_module);if(r-main-count!1){if(r-discard_body){r-read_event_handlerngx_http_discarded_request_body_handler;ngx_add_timer(r-connection-read,clcf-lingering_timeout);if(r-lingering_time0){r-lingering_timengx_time()(time_t)(clcf-lingering_time/1000);}}ngx_http_close_request(r,0);return;}rr-main;if(r-connection-read-eof){ngx_http_close_request(r,0);return;}if(r-reading_body){r-keepalive0;r-lingering_close1;}if(!ngx_terminate!ngx_exitingr-keepaliveclcf-keepalive_timeout0){ngx_http_set_keepalive(r);return;}if(clcf-lingering_closeNGX_HTTP_LINGERING_ALWAYS||(clcf-lingering_closeNGX_HTTP_LINGERING_ON(r-lingering_close||r-header_in-posr-header_in-last||r-connection-read-ready||r-connection-pipeline))){ngx_http_set_lingering_close(r-connection);return;}ngx_http_close_request(r,0);}2 目的ngx_http_finalize_connection是 HTTP 请求处理完毕后的连接归宿决策函数在一个请求的所有响应数据已发送完毕之后决定该 TCP 连接的下一个命运是保持长连接keepalive、延迟关闭lingering close还是立即关闭。3 详解1 函数签名staticvoidngx_http_finalize_connection(ngx_http_request_t*r)1 返回值void该函数不返回状态码——它的职责是无条件地将请求的连接导向某个终态无论走哪个分支最终连接必定进入 keepalive、lingering close 或直接关闭三者之一。因此不存在失败返回的场景所有错误处理由下游函数如ngx_http_close_request内部完成。2 函数名ngx_http_finalize_connection词段含义ngx_Nginx 标准前缀http_属于 HTTP 模块finalize收尾、结束——表示这是请求处理生命周期的最后一步connection操作对象是连接级别——决定 TCP 连接的去留3 参数列表参数名类型含义来源约束rngx_http_request_t*当前 HTTP 请求对象调用方ngx_http_finalize_request非空可能是子请求此时r ! r-main2 逻辑流程ngx_http_finalize_connection(r) │ ├── [1] HTTP/2 流快速通道 │ └── r-stream ! NULL → ngx_http_close_request(r, 0)直接返回 │ ├── [2] 子请求/并发引用检测主请求引用计数 1 │ ├── [2.1] 需要丢弃请求体discard_body │ │ ├── 设置 read_event_handler ngx_http_discarded_request_body_handler │ │ ├── 启动 lingering_timeout 读定时器 │ │ └── lingering_time 未设置 → 初始化为当前时间 lingering_time │ └── [2.2] 统一关闭子请求 │ └── ngx_http_close_request(r, 0) 递减引用计数返回 │ ├── [3] 切换到主请求r r-main │ ├── [4] 客户端已关闭连接 │ └── r-connection-read-eof → ngx_http_close_request(r, 0)返回 │ ├── [5] 未读完请求体 → 补救标记 │ └── r-reading_body → keepalive0, lingering_close1 │ ├── [6] Keepalive 长连接复用 │ └── 条件!ngx_terminate !ngx_exiting r-keepalive keepalive_timeout0 │ → ngx_http_set_keepalive(r)返回 │ ├── [7] Lingering Close 延迟关闭 │ └── 条件lingering_close ALWAYS │ 或 lingering_close ON (r-lingering_close │ 或 header_in 有残留 │ 或 read-ready │ 或 pipeline) │ → ngx_http_set_lingering_close(r-connection)返回 │ └── [8] 兜底立即关闭连接 └── ngx_http_close_request(r, 0){ngx_http_core_loc_conf_t*clcf;}局部变量声明clcf用于缓存当前 location 的核心模块配置在多个分支中使用keepalive_timeout、lingering_close、lingering_time、lingering_timeout等字段。1 HTTP/2 流快速通道#if(NGX_HTTP_V2)if(r-stream){ngx_http_close_request(r,0);return;}#endif进入条件编译时启用 HTTP/2 支持NGX_HTTP_V2且r-stream非空。r-stream是ngx_http_v2_stream_t*类型定义在ngx_http_request.h:453仅当请求通过 HTTP/2 多路复用连接建立时才非空。处理逻辑HTTP/2 的连接生命周期由流控制模块管理——一个 TCP 连接上同时存在多个流关闭单一请求不应影响整个连接。因此直接调用ngx_http_close_request(r, 0)递减主请求引用计数并释放当前请求对象但不关闭底层 TCP 连接——连接是否关闭由 HTTP/2 模块在ngx_http_v2_close_stream中自行判断。设计意图将 HTTP/2 的 connection-level finalization 职责下放给 HTTP/2 模块本函数只处理 HTTP/1.x 的纯连接生命周期。#if条件编译确保未启用 HTTP/2 时无额外开销。2 子请求/并发引用检测if(r-main-count!1){if(r-discard_body){r-read_event_handlerngx_http_discarded_request_body_handler;ngx_add_timer(r-connection-read,clcf-lingering_timeout);if(r-lingering_time0){r-lingering_timengx_time()(time_t)(clcf-lingering_time/1000);}}ngx_http_close_request(r,0);return;}进入条件r-main-count ! 1。r-main-countngx_http_request.h:459unsigned count:16位域是主请求的引用计数器当存在活跃的子请求subrequest或请求被其他模块持有引用时count 1。正常单一请求处理时count 1。2.1 丢弃请求体子步骤进入条件r-discard_body为12.2 统一关闭子请求无论是否设置了discard_body最终都调用ngx_http_close_request(r, 0)递减主请求的引用计数然后函数返回。此时子请求本身已完结本函数在该子请求的上下文中做完收尾后退出真正释放连接的工作留给最后一个引用释放时触发。ngx_http_close_request函数定义在src/http/ngx_http_request.c。核心逻辑r r-main切换到主请求→r-count--递减引用计数→再调用ngx_http_close_connection关闭 TCP 连接。