cosoket chunk reader返回数据最大为4090字节

201 views
Skip to first unread message

helin...@gmail.com

unread,
Sep 28, 2018, 8:20:57 AM9/28/18
to openresty
1. 现象
使用pintsized/lua-resty-http库获取服务端的chunk数据,不管服务端一次发送数据量多大,一次reader()调用获取到的最大数据量只有4090个字节。

2.  chunk reader代码如下:
  location /genericinterface {
    content_by_lua_block {

      local http = require "resty.http"
      local httpc = http.new()

      -- The generic form gives us more control. We must connect manually.
      httpc:set_timeout(500)
      httpc:connect("127.0.0.1", 80)

      -- And request using a path, rather than a full URI.
      local res, err = httpc:request({
          path = "/helloworld",
          headers = {
              ["Host"] = "example.com",
          },
      })

      if not res then
        ngx.say("failed to request: ", err)
        return
      end

      -- Now we can use the body_reader iterator, to stream the body according to our desired chunk size.
      local reader = res.body_reader

      repeat
        local chunk, err = reader(8192)   <--- 返回chunk最大数据量为4090字节
        if err then
          ngx.log(ngx.ERR, err)
          break
        end

        if chunk then
          -- process
        end
      until not chunk


3. 思考
  -.  从resty.http的源码看,是通过ngx.socket.tcp来实现chunk body read(具体见_chunked_body_reader方法)的,所以怀疑是tcp read buffer的限制。
  -. 调整系统参数如下:
      net.ipv4.tcp_rmem = 8760 256960 4088000
      net.ipv4.tcp_wmem = 8760 256960 4088000

     但是验证结果还是最大读取到数据只有4090字节
net.ipv4.tcp_wmem = 8760  256960  4088000

helin...@gmail.com

unread,
Sep 28, 2018, 10:02:15 AM9/28/18
to openresty
另外补充一下,在reader节点上用tcpdump抓包分析,接收到chunk数据长度分别有5672Bytes和7454Bytes,但是resty.http读到的chunk长度却变了,最大只有4096Bytes

在 2018年9月28日星期五 UTC+8下午8:20:57,helin...@gmail.com写道:

amms...@gmail.com

unread,
Sep 29, 2018, 5:15:41 AM9/29/18
to openresty
有试过lua_socket_buffer_size 这个配置吗


在 2018年9月28日星期五 UTC+8下午8:20:57,helin...@gmail.com写道:
1. 现象

helin...@gmail.com

unread,
Nov 8, 2018, 9:22:38 PM11/8/18
to openresty
多谢回复,lua_socket_buffer_size确实没有配置。

在 2018年9月29日星期六 UTC+8下午5:15:41,amms...@gmail.com写道:

Frank Yu

unread,
Nov 8, 2018, 9:37:02 PM11/8/18
to open...@googlegroups.com
client_body_buffer_size client_max_body_size 调整一下这两个参数呢?

<helin...@gmail.com> 于2018年11月9日周五 上午10:22写道:
--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html

helin...@gmail.com

unread,
Mar 26, 2019, 8:59:38 AM3/26/19
to openresty
设置lua_socket_buffer_size为100k,问题还是没有解决


在 2018年9月29日星期六 UTC+8下午5:15:41,amms...@gmail.com写道:
有试过lua_socket_buffer_size 这个配置吗

helin...@gmail.com

unread,
Mar 26, 2019, 9:00:37 AM3/26/19
to openresty

client_body_buffer_size client_max_body_size都设置为20m,题中的现象还是重现
在 2018年11月9日星期五 UTC+8上午10:37:02,Frank Yu写道:
Message has been deleted

helin...@gmail.com

unread,
Mar 27, 2019, 3:58:54 AM3/27/19
to openresty

@agentzh  麻烦指点迷津,谢谢。

目前buffer配置如下:
    server {
        listen 10261;
        location / {
            client_max_body_size 20m;
            client_body_buffer_size 20m;
            lua_socket_buffer_size 16k;
            content_by_lua_block {
                ...
           }
       }
}
      

在 2018年9月28日星期五 UTC+8下午10:02:15,helin...@gmail.com写道:

Frank Yu

unread,
Mar 27, 2019, 4:50:27 AM3/27/19
to open...@googlegroups.com
  1. client_body_timeout 10s;
  2. client_header_timeout 10s;
  3. client_body_in_single_buffer on; #这个directive让Nginx将所有的request body存储在一个缓冲当中,它的默认值是off。启用它可以优化读取$request_body变量时的I/O性能
设置一下这几个参数呢?可能是太大了超时了。你可以在access log中打印一下http code看一下是不是403,413之类的。同步日志级别调整为debug,看一下是否有过早断开连接之类的错误。根据我的实践经验4k不是瓶颈,128k的我都试过,但是随着body的增大,超时概率会显著增加。

<helin...@gmail.com> 于2019年3月27日周三 下午3:58写道:
--

tweyseo

unread,
Mar 27, 2019, 9:06:49 PM3/27/19
to openresty
你好,你的代码中无法确定收到的http报文是否是chunked编码的,所以也有可能拿到的是_body_reader,而源码中_body_reader的449行和458行的逻辑均为不按照给定的max_chunk_size来收取报文的,所以建议具体再通过log或者仔细解读抓包文件来确定下。


在 2018年9月28日星期五 UTC+8下午8:20:57,helin...@gmail.com写道:
1. 现象

Appla lol

unread,
Mar 28, 2019, 3:34:03 AM3/28/19
to open...@googlegroups.com

--

helin...@gmail.com

unread,
Mar 28, 2019, 5:03:50 AM3/28/19
to openresty
谢谢Frank Yu, tweyseo, Appla的耐心回复。我的问题已经解决了。

背景及原因如下:

- 背景:
因为cosocket stream无法支持https双向认证访问后端backend,所以选择中间增加了一级http proxy. 流程如下:
client --> oprenresty port 10261(cosocket stream) --> openresty port 10262(http proxy) --> backend server

其中: 
client --> oprenresty port 10261(cosocket stream) --> openresty port 10262是http通信
openresty port 10262 --> backend server 是https通信

- 现象:
backend server返回的chunk数据5k+,分成2个packets(第一个packet带有chunk size信息,第二个packet是纯数据)。而在openresty port 10261的cosocket stream处理读取到了2个chunk数据。

- 原因:
openresty port 10262(http proxy)设置成proxy_buffer: off,造成openresty重新解包封包生成了2个chunk数据。

- 解决方案:
openresty port 10262(http proxy)其中增加proxy配置如下:
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 24 8k;
proxy_busy_buffers_size 16k;

在 2019年3月27日星期三 UTC+8下午3:58:54,helin...@gmail.com写道:
Reply all
Reply to author
Forward
0 new messages