15 nginx 中默认的 proxy_buffering 导致基于 http 的流式响应存在 buffer, 以 4kb 一批次返回
前言
这也是最近碰到的一个问题
直连 流式 http 服务, 发现 流式响应正常, 0.1 秒接收到一个响应
但是 经过 nginx 代理一层之后, 就发现了 类似于缓冲的效果, 1秒接收到 10个响应
最终 调试 发现是 nginx 的 proxy_buffering 配置引起的
然后 更新 proxy_buffering 为 off 解决了这个问题
这里 主要是 来调试一下 这个 proxy_buffering 的影响
测试用例
可以参见 http 协议中如何实现流式的交互数据
这里为了方便问题复现, 做了一些 小调整, 增加了 响应的数据量, 减少了 sleep
客户端这边如下, 直接访问服务 8080, 可以看到 0.01 秒 1 个响应
切换成基于 nginx 访问服务, 现象是 2秒一堆响应
nginx 配置如下, 将 proxy_buffering 设置为 off, 则基于原服务, nginx 效果一致 了
proxy_buffering 为 false 的调用链路
这个看着比较直观, 每一次 upstream 响应数据了, nginx接收到了数据, 然后直接 响应给下游服务
这里 out->buf 为 响应头
out->next->buf 为 chunked_body_filter 封装的一个响应, 我们这里不用关心
out->next->next->buf 为 nginx 接收到 upstream 的一次响应
第二次断点, 因为第一个断点有停留, 服务器在不断地响应数据, 所以 nginx 这边拿到了 服务器的N次响应, 这里 一起响应给客户端
proxy_buffering 为 true 的调用链路
可以看到 第一次响应给下游服务, nginx 就拿到了 N 个响应
然后 这里的 buffer 主要是基于 ngx_event_pipe_write_to_downstream 中的管道的策略进行控制的, 存在一定的 buffer, buffer 满了之后, 一次性刷新数据到 下游服务
判断刷新的地方 是在这里
然后这个阈值 可以通过 proxy_busy_buffers_size 进行配置
nginx 中调试如下
完