proxy_buffering 开着,流式响应会不会被攒住?慢 client 到底占用谁的资源?gzip 对 SSE 又有什么影响?这篇用一个能控制节奏的上游和 nginx 1.31.6 量出来,和常见的说法对一对。
数据块大小 | 配置 | 收到第一批响应体 | 收到一半字节 | 收完 | recv 次数 ---------+------------------------------------+----------+--------+--------+-------- 100 字节 | buffering on(默认) | 0.00 s | 1.04 s | 2.07 s | 11 100 字节 | buffering off | 0.00 s | 1.03 s | 2.06 s | 11 100 字节 | on + 上游发 X-Accel-Buffering: no | 0.00 s | 1.03 s | 2.06 s | 11 100 字节 | on + gzip on(压缩 text/event-stream) | 2.09 s | 2.09 s | 2.09 s | 1 16384 字节 | buffering on(默认) | 0.00 s | 1.04 s | 2.07 s | 11 16384 字节 | buffering off | 0.00 s | 1.04 s | 2.08 s | 14 16384 字节 | on + 上游发 X-Accel-Buffering: no | 0.00 s | 1.04 s | 2.07 s | 12 16384 字节 | on + gzip on(压缩 text/event-stream) | 2.06 s | 2.06 s | 2.06 s | 1
缓冲打开时 nginx 也会随到随转发,小块不会被攒到最后;gzip 才会。
配置 | 上游写完 40 MB 用了 | client 收完用了 | worker 打开的临时文件最大 --------------------------------+---------------+-------------+----------------- buffering on(默认) | 0.0 s | 11.3 s | 38.9 MB on + proxy_max_temp_file_size 0 | 9.2 s | 11.3 s | 0.0 MB buffering off | 10.1 s | 11.3 s | 0.0 MB 缓冲打开且允许写临时文件时,看“上游写完”那一列:nginx 把响应整个收下来(放进 proxy_temp_path 下的临时文件,最后一列是它的大小;nginx 打开后立刻 unlink 目录项,目录里看不到,所以用 lsof 量),上游连接早早释放,client 再慢也只占 nginx 的磁盘。不允许写临时文件或关掉缓冲时,上游被拖到接近 client 的速度(上游写完的时间接近 client 收完的时间,差的部分是内核 socket 缓冲吸收的)
缓冲打开时 nginx 用临时文件吸收整个响应,上游很快释放;关掉缓冲上游被占到 client 收完。