buffer 问题
由于“各路”buffer
的存在,如果包比较小的话BigPipe
的chunked
输出很可能会被buffer
住。
解决方案
- 填充空格:将一次
flush
的数据填充到buffer_size
。 - 调小
buffer
,让数据更容易达到buffer_size
。 - 关闭
buffer
。
Nginx 负载 buffer
对于 Nginx 来说,会有 proxy_buffer
和 fastcgi_buffer
。第一种方式,不用调整 buffer,但这种方式很不优雅,而且增加了带宽,并不是很合理。至于调小 buffer,这看起来是一个很好的思路,然而对于 gzip 过的数据来说,最小的 buffer 可能也比较大。
- 选择了关闭
proxy_buffer
和fastcgi_buffer
关闭 proxy_buffer
的指令 proxy_buffering off
原生就支持。而关闭 fastcgi_buffer
的 fastcgi_buffering
需要1.5.6版本。
1 | Syntax: fastcgi_buffering on | off; |
这种方式对所有请求都关闭 buffer
- 用 http header,用于关闭 buffer
Buffering can also be enabled or disabled by passing “yes” or “no” in the “X-Accel-Buffering” response header field. This capability can be disabled using the fastcgi_ignore_headers directive.
因此,配置上完全不用关闭 buffer,只需要在代码中加 header 就好,顺利把 buffer 优雅关闭
1 | header('X-Accel-Buffering: no'); |
在需要关闭 nginx 的 buffer 的请求响应添加 X-Accel-Buffering 头:
response.addHeader(“X-Accel-Buffering”, “no”);
- 其他问题
1 | http { |
其实读可以这么理解上面的配置,nginx会在攒够一块儿缓冲区的量后,将一块儿数据发出去。上面我们配置了fastcgi_buffers 16 1k; 就是16块儿,大小为1K的缓存。
我们的数据量太小了,连默认的一块儿缓冲区都填不满,没法看到分块儿发送的效果,所以这里我们将缓冲区给调小为1K,这样就能1K为单位分块儿,1K一发,体现出实验效果了。
ios 系统 buffer 问题
- 经过 nginx 负载
首屏内容最少要 200 个字符(html标签、css样式、js代码不算在内),同时需要配置 X-Accel-Buffering 头才会分块 flush
- 不经过 nginx 负载
首屏内容最少要 200 个字符(html标签、css样式、js代码不算在内),无需配置 X-Accel-Buffering 头
android 系统 buffer 问题
配置 X-Accel-Buffering 头,首屏内容超过 200 字符都不能分块 flush