BigPipe 分块输出遇到的问题

buffer 问题

由于“各路”buffer的存在,如果包比较小的话BigPipechunked输出很可能会被buffer住。

解决方案

  1. 填充空格:将一次flush的数据填充到 buffer_size
  2. 调小buffer,让数据更容易达到 buffer_size
  3. 关闭buffer

Nginx 负载 buffer

对于 Nginx 来说,会有 proxy_bufferfastcgi_buffer。第一种方式,不用调整 buffer,但这种方式很不优雅,而且增加了带宽,并不是很合理。至于调小 buffer,这看起来是一个很好的思路,然而对于 gzip 过的数据来说,最小的 buffer 可能也比较大。

  • 选择了关闭 proxy_bufferfastcgi_buffer

关闭 proxy_buffer 的指令 proxy_buffering off 原生就支持。而关闭 fastcgi_bufferfastcgi_buffering 需要1.5.6版本。

1
2
3
4
Syntax: fastcgi_buffering on | off;
Default: fastcgi_buffering on;
Context: http, server, location
This directive appeared in version 1.5.6.

这种方式对所有请求都关闭 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
2
3
4
5
6
http {
....
fastcgi_buffer_size 1k;
fastcgi_buffers 16 1k;
....
}

其实读可以这么理解上面的配置,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

  • 本文作者: forever杨
  • 本文链接: https://blog.yl-online.top/posts/b0407ea6.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。如果文章内容对你有用,请记录到你的笔记中。本博客站点随时会停止服务,请不要收藏、转载!