news 2026/5/7 9:46:23

ngx_http_close_connection

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ngx_http_close_connection

1 定义

ngx_http_close_connection 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_request.c
voidngx_http_close_connection(ngx_connection_t*c){ngx_pool_t*pool;ngx_log_debug1(NGX_LOG_DEBUG_HTTP,c->log,0,"close http connection: %d",c->fd);#if(NGX_HTTP_SSL)if(c->ssl){if(ngx_ssl_shutdown(c)==NGX_AGAIN){c->ssl->handler=ngx_http_close_connection;return;}}#endif#if(NGX_STAT_STUB)(void)ngx_atomic_fetch_add(ngx_stat_active,-1);#endifc->destroyed=1;pool=c->pool;ngx_close_connection(c);ngx_destroy_pool(pool);}
ngx_http_close_connection 函数用于 彻底关闭一个 HTTP 连接,是连接生命周期的最后一步。

2 详解

1 函数签名

voidngx_http_close_connection(ngx_connection_t*c)
返回值类型:void 该函数不向调用者返回任何值。
参数 ngx_connection_t *c 一个指向 ngx_connection_t 结构体的指针。 该结构体是 Nginx 对每个 TCP 连接的抽象 函数需修改该连接的状态

2 逻辑流程

1 局部变量 2 调试日志 3 SSL 关闭处理 4 统计桩更新 5 关闭连接

1 局部变量
{ngx_pool_t*pool;

2 调试日志
ngx_log_debug1(NGX_LOG_DEBUG_HTTP,c->log,0,"close http connection: %d",c->fd);

3 SSL 关闭处理
#if(NGX_HTTP_SSL)if(c->ssl){if(ngx_ssl_shutdown(c)==NGX_AGAIN){c->ssl->handler=ngx_http_close_connection;return;}}#endif
判断当前连接是否启用了 SSL/TLS 层 若为非 SSL 明文连接,跳过整个 SSL 关闭流程; 若为 SSL 连接,则必须执行 TLS 规范要求的关闭通知握手机制 调用 ngx_ssl_shutdown 启动 SSL 层面的优雅关闭握手。 该函数会尝试发送 close_notify 警报并向对端告知连接即将关闭。 因为 Nginx 工作在所有 socket 非阻塞模式下, 该操作可能无法一次完成(底层 TCP 发送缓冲区满或还需接收对方响应), 此时返回 NGX_AGAIN 表示“需要稍后重试” 将 SSL 层的回调句柄 handler 设置为当前函数自身 当 SSL 关闭需要异步等待事件时,Nginx 不阻塞 worker 进程。 而是约定当 socket 再次可读/写时,事件模块会间接调用 c->ssl->handler。 这里将句柄指向自身,形成一个可重入的状态机: 下次事件触发时将继续执行本函数,继续尝试 SSL 关闭握手,直到彻底完成 立即从函数返回,不执行后续的 socket 关闭和内存池销毁。 逻辑: 因为 SSL 关闭尚未完成, 底层 socket 仍需保持打开用以收发 close_notify 消息。 此时直接返回,暂停清理流程,等待事件驱动下一次调用

4 统计桩更新
#if(NGX_STAT_STUB)(void)ngx_atomic_fetch_add(ngx_stat_active,-1);#endif
原子地将全局变量 ngx_stat_active 减 1 活跃连接计数器在连接建立时递增,在此处递减,精确反映当前正在处理的 HTTP 连接数

5 关闭连接
c->destroyed=1;pool=c->pool;ngx_close_connection(c);ngx_destroy_pool(pool);}
#1 将连接结构体中的 destroyed 标志置为 1。 这是一个防止重入的守护标志。 在其他事件回调中(如读/写完成处理),会首先检查 c->destroyed, 若已置 1 则直接返回,避免对即将或已被回收的连接进行操作,杜绝野指针和双重释放。
#2 将连接的内存池地址保存到局部变量 pool 中 由于下一行 ngx_close_connection(c) 会回收 c 结构(可能将字段清零或将其放回空闲链表), 之后无法再通过 c->pool 安全地引用内存池。 提前保存保证了无论连接结构如何回收,最终都能正确销毁整个内存池。
#3 执行底层 TCP 连接的关闭和连接结构回收
#4 销毁之前保存的连接内存池 pool。 该内存池为本次 HTTP 连接期间所有内存分配(请求结构、缓冲、临时变量等)提供记忆。 销毁它会一次性高效回收所有关联内存,彻底完成连接生命周期末端的资源清理。 使用保存的 pool 而非 c->pool,确保了调用安全。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/7 9:44:24

FastMCP 服务说明文档

1. 服务概述 一句话简介:支持客户端会话管理的MCP服务器TypeScript框架,提供简单易用的工具、资源和提示词定义能力。 服务名称:FastMCP版本号:Latest开发者/提供方:yamato-snow协议类型:MCP (Model Cont…

作者头像 李华
网站建设 2026/5/7 9:43:55

RK3288开发板Ubuntu系统镜像DIY:从解包update.img到定制自己的rootfs

RK3288开发板Ubuntu系统深度定制指南:从固件解构到个性化镜像制作 1. 理解RK3288固件架构与定制原理 RK3288作为瑞芯微经典的ARM Cortex-A17架构处理器,在工业控制、智能终端等领域仍有广泛应用。与简单的系统备份不同,深度定制需要先理解其固…

作者头像 李华
网站建设 2026/5/7 9:43:03

c++面向对象——运算符重载

运算符重载c运算符c中的运算符:可以分为单目、二目、三目运算符。单目运算符只有一个操作数,二目运算符有两个操作数,三目运算符有三个操作数。也可叫做一元、二元、三元运算符。单目运算符:a a a-- --a …

作者头像 李华
网站建设 2026/5/7 9:40:36

Flask异步时代的降临:掌握 Flask 2.0+ 的 `async def` 视图与协程编写

更多内容请见: 《Python Web项目集锦》 - 专栏介绍和目录 文章目录 前言:历史的分水岭 第一章:认知升级——从 WSGI 到 ASGI 的底层跃迁 1.1 WSGI 的“同步枷锁” 1.2 ASGI 的“异步解放” 第二章:基础设施换血——告别 Werkzeug,拥抱 ASGI 服务器 2.1 为什么异步视图不能…

作者头像 李华