nghttp2_session_get_remote_window_size 解析:nghttp2 中 HTTP/2 连接级流控窗口查询 API
nghttp2_session_get_remote_window_size 解析nghttp2 中 HTTP/2 连接级流控窗口查询 API【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit本篇围绕 nghttp2 库的nghttp2_session_get_remote_window_size()API 展开它是查询一条 HTTP/2 连接上“连接级远端窗口大小”的只读接口是理解 nghttp2 流控Flow Control机制的关键入口。读完本篇你将掌握该函数的原型、返回值语义、底层字段session-remote_window_size的完整生命周期初始化、消耗、回补以及它在发送调度和实际服务端代码中如何被使用。函数原型与基本语义该 API 的官方参考文档位于 nghttp2_session_get_remote_window_size.rst其核心内容如下#include nghttp2/nghttp2.h int32_t nghttp2_session_get_remote_window_size(nghttp2_session *session);功能Returns the remote window size for a connection返回该连接的远端窗口大小参数session—— 指向nghttp2_session结构体的指针即当前这条 HTTP/2 会话返回值int32_t类型的连接级远端窗口大小可靠性文档明确说明This function always succeeds该函数永远成功。这里需要澄清一个 HTTP/2 协议的常见混淆点“远端窗口”指对端remote endpoint允许本端发送的流量额度而不是本端允许接收的额度。按 HTTP/2 流控规则发送方在发出受流控的载荷如 DATA 帧前必须同时满足流级窗口和连接级窗口的限制对端会通过WINDOW_UPDATE帧归还额度。因此这个值越大本端可“在途”发送的数据越多。初始值与常量定义nghttp2 中连接级窗口的初始值由常量NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE决定在头文件中的定义为/* lib/includes/nghttp2/nghttp2.h#L237 */ #define NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE ((1 16) - 1)即65535 字节与 HTTP/2 协议默认初始窗口一致。会话创建时该值被写入 session 结构体见 nghttp2_session.c#L458(*session_ptr)-remote_window_size NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;实现分析一个“直读字段”的只读函数从 nghttp2_session.c#L7414-L7416 可以看到该函数的实现极为直接int32_t nghttp2_session_get_remote_window_size(nghttp2_session *session) { return session-remote_window_size; }没有任何锁、校验或失败路径——这与文档“永远成功”的描述完全吻合。要理解这个 API 的价值关键是弄清session-remote_window_size字段在源码中被哪些路径修改即它的生命周期1. 消耗发送 DATA 帧时扣减每当向对端发出 DATA 帧连接级与流级窗口同步扣减见 nghttp2_session.c#L2474-L2476session-remote_window_size - (int32_t)frame-hd.length; ... stream-remote_window_size - (int32_t)frame-hd.length;2. 回补收到 WINDOW_UPDATE 时增加当解析到对端发来的WINDOW_UPDATE帧时按目标区分连接级/流级回补见 nghttp2_session.c#L4631-L4635session-remote_window_size frame-window_update.window_size_increment;流级的对应逻辑在同文件稍后位置stream-remote_window_size ...。此外若对端通过SETTINGS_INITIAL_WINDOW_SIZE调整初始窗口也会对窗口值做相应修正这一点在流级窗口的注释中有明确提示见下文。3. 发送调度门槛窗口 0 时阻塞数据发送session-remote_window_size不只是“可查询的统计值”它还是 nghttp2 出站调度的硬性闸门。在获取/弹出下一个待发帧项时只有连接级窗口为正才会从调度器中取出受流控的待发项典型为 DATA 相关载荷见 nghttp2_session.c#L2279-L2281if (session-remote_window_size 0) { return session_sched_get_next_outbound_item(session); } return NULL;同一判断也出现在nghttp2_session_pop_next_ob_item()中nghttp2_session.c#L2313-L2317。也就是说连接级远端窗口耗尽时nghttp2 会主动挂起受流控数据的发送直到 WINDOW_UPDATE 回补窗口。这也是该 API 对流控排障最重要的意义——它直接反映了“本端现在能不能继续发数据”。与流级窗口的关系min(流级, 连接级)nghttp2 对每个窗口都成对提供“连接级”与“流级”查询函数二者缺一不可。头文件注释明确给出了两者关系见 nghttp2.h#L3891-L3906* Returns the remote window size for a given stream |stream_id|. * * This is the amount of flow-controlled payload (e.g., DATA) that the * local endpoint can send without stream level WINDOW_UPDATE. There * is also connection level flow control, so the effective size of * payload that the local endpoint can actually send is * min(nghttp2_session_get_stream_remote_window_size(), * nghttp2_session_get_remote_window_size()).即本端实际可发送的受流控载荷上限为min(nghttp2_session_get_stream_remote_window_size(), nghttp2_session_get_remote_window_size())两者的实现差异也值得注意。流级版本在找不到对应流时返回 -1且会把负值钳制为 0见 nghttp2_session.c#L7400-L7412int32_t nghttp2_session_get_stream_remote_window_size(nghttp2_session *session, int32_t stream_id) { nghttp2_stream *stream; stream nghttp2_session_get_stream(session, stream_id); if (stream NULL) { return -1; } /* stream-remote_window_size can be negative when SETTINGS_INITIAL_WINDOW_SIZE is changed. */ return nghttp2_max_int32(0, stream-remote_window_size); }注意源码注释当对端通过SETTINGS_INITIAL_WINDOW_SIZE缩小初始窗口时流级窗口可能出现负值因此查询接口将其钳制为 0。相比之下连接级的nghttp2_session_get_remote_window_size()直接返回原始字段值、不做钳制这与文档“always succeeds”指调用本身不会失败并不矛盾——调用必成功但读到的数值语义需要调用方结合流控状态理解。另外不要把它与“本端接收窗口”系列 API 混淆。同区域的nghttp2_session_get_local_window_size()本端还能接收多少数据实现为local_window_size - recv_window_size见 nghttp2_session.c#L7396-L7398与nghttp2_session_get_effective_local_window_size()见 nghttp2_session.c#L7391-L7394描述的是接收方向的额度方向恰好相反API方向语义nghttp2_session_get_remote_window_size()发送方向对端允许本端发送的连接级额度nghttp2_session_get_stream_remote_window_size()发送方向对端允许本端发送的流级额度nghttp2_session_get_local_window_size()接收方向本端允许对端发送的剩余连接级额度nghttp2_session_get_effective_local_window_size()接收方向本端接收窗口的有效配置值已计入本地nghttp2_submit_window_update()调整实际使用示例判断流控阻塞nghttp2 自带示例服务器中有一个典型用法在on_frame_sent回调里利用该 API 判断某条流是否已被流控阻塞从而决定是否为该流启用写超时见 HttpServer.cc#L1590-L1601} else if (std::min(nghttp2_session_get_stream_remote_window_size( session, frame-hd.stream_id), nghttp2_session_get_remote_window_size(session)) 0) { // If stream is blocked by flow control, enable write timeout. add_stream_read_timeout_if_pending(stream); add_stream_write_timeout(stream); }这正是前述min(流级, 连接级)判断的直接落地两者任一为 0或更小即认为数据发送被流控挂起。这一模式对需要监控 HTTP/2 客户端/服务端吞吐的应用有参考价值——当观察到发送停滞而连接未断时首先应检查这两个窗口值。在 fluent-bit 中的位置在 fluent-bit 仓库中nghttp2 以 vendored 源码形式内置于 lib/nghttp2-1.65.0/支撑其 HTTP/2 客户端见 flb_http_client_http2.c 等文件与使用 HTTP/2 的后端交互。从源码结构看fluent-bit 自身的代码并未直接调用nghttp2_session_get_remote_window_size()连接级与流级窗口的扣减、回补、发送挂起均由 nghttp2 会话内部机制透明处理该 API 更适合作为底层诊断与集成扩展时的观测手段。该 API 文档也是 nghttp2 官方 API 参考的组成部分被收录在文档构建清单 CMakeLists.txt#L101 与 Makefile.am#L149 中。使用建议小结发送前预估发送大块 DATA 前用min(get_stream_remote_window_size(), get_remote_window_size())估算可发额度流控排障发送停滞时优先观察连接级窗口是否为 0并确认对端是否停止发送WINDOW_UPDATE区分方向涉及“本端能收多少”时请改用nghttp2_session_get_local_window_size()系列避免把发送窗口误读为接收窗口数值语义调用本身永不失败但数值语义受对端SETTINGS_INITIAL_WINDOW_SIZE调整影响流级查询接口对负值的钳制处理nghttp2_max_int32(0, ...)是理解这类边界情况的直接依据。【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Yuxi Web 前端开发约定实践指南:Vue 3 / Vite 多租户知识智能体平台的前端工程规范

Yuxi Web 前端开发约定实践指南:Vue 3 / Vite 多租户知识智能体平台的前端工程规范

Yuxi Web 前端开发约定实践指南:Vue 3 / Vite 多租户知识智能体平台的前端工程规范 【免费下载链接】Yuxi 可私有部署的多租户知识智能体平台:统一 RAG、知识图谱、多智能体、MCP/Skills、沙盒与权限管理。Self-hosted knowledge agent platform for RAG…

2026/9/20 11:10:21 阅读更多 →
不随行父母同意书公证怎么办理?从材料准备到出证,全程在线完成

不随行父母同意书公证怎么办理?从材料准备到出证,全程在线完成

很多家长接触不随行父母同意书公证时,都会觉得流程复杂、来回跑公证处太折腾。其实现在不用线下排队,从材料上传、身份核验到出证邮寄,全流程都能在线完成,在家就能把这份涉外出行必备的公证办好。公证认证百科http://www.gongzhe…

2026/9/20 7:46:18 阅读更多 →
Redis Search替代Elasticsearch的适用场景与性能实践

Redis Search替代Elasticsearch的适用场景与性能实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 14:47:12 阅读更多 →

最新新闻

压印底层图解原理:3步读懂Java对象内存与GC机制

压印底层图解原理:3步读懂Java对象内存与GC机制

压印底层图解原理:3步读懂Java对象内存与GC机制 盯着满屏红色的 StackTrace 报错,你是不是只想砸键盘?别慌,这通常是 JVM 内存模型里的“压印”机制在作怪。很多初学者看到 OutOfMemoryError 或…

2026/9/22 0:47:13 阅读更多 →
苏宁业绩图解原理:3个代码实战破解源码阅读难题

苏宁业绩图解原理:3个代码实战破解源码阅读难题

苏宁业绩图解原理:3个代码实战破解源码阅读难题 看了一堆教程还是不会写项目?这痛点我太懂了。别急,今天咱们不整虚的,直接上苏宁业绩图解原理。很多应届生朋友问我,为什么看源码像看天书?因为没人给你拆解底层逻辑。…

2026/9/22 0:47:13 阅读更多 →
3天搞定穆斯林的葬礼读后感保姆级教程避坑指南

3天搞定穆斯林的葬礼读后感保姆级教程避坑指南

3天搞定穆斯林的葬礼读后感保姆级教程避坑指南 官方文档太长抓不住重点?别慌,这本《穆斯林的葬礼》的读后感其实有套固定的底层逻辑。很多转岗或者跨行写书评的朋友,一上来就陷入“剧情复述”的泥潭,越写越偏,最后像流水账。…

2026/9/22 0:47:13 阅读更多 →
搞定ADCM4高频面试题,源码拆解助你通关

搞定ADCM4高频面试题,源码拆解助你通关

搞定ADCM4高频面试题,源码拆解助你通关 看了一堆教程还是不会写项目?别慌,很多兄弟都卡在这。其实你缺的不是知识,而是把散落知识点串成逻辑的能力。最近ADCM4成了高频面试题,但大多数回答都停留在背概念,面试官根本听不进去。…

2026/9/22 0:47:13 阅读更多 →
2026最新十一月性能优化:3个技巧搞定StackTrace报错

2026最新十一月性能优化:3个技巧搞定StackTrace报错

2026最新十一月性能优化:3个技巧搞定StackTrace报错 凌晨两点,线上告警炸了。你盯着控制台,满屏红色的 Stack Trace 像天书一样堆叠。 NullPointerException…

2026/9/22 0:47:13 阅读更多 →
5个新手避坑技巧,看说实战让公路项目代码跑通

5个新手避坑技巧,看说实战让公路项目代码跑通

5个新手避坑技巧,看说实战让公路项目代码跑通 学会语法却不知怎么搭项目,这是很多刚入行公路工程信息化开发的兄弟最头疼的事。你背下了 Python 的 if-else ,记住了 Java…

2026/9/22 0:46:12 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →