谢谢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写道:
@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写道:
另外补充一下,在reader节点上用tcpdump抓包分析,
接收到chunk数据长度分别有5672Bytes和7454Bytes,但是resty.http读到的chunk长度却变了,最大只有4096Bytes
在 2018年9月28日星期五 UTC+8下午8:20:57,helin...@gmail.com写道: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