客户端cosocket的TCP_NODELAY没有设置

245 views
Skip to first unread message

aaashun

unread,
Aug 17, 2014, 3:23:41 AM8/17/14
to open...@googlegroups.com
本周测试websocket时发现一个简单的ping服务端要40ms左右才收到, 40ms是一个很有代表意义的延时.
nginx.conf里的设置是tcp_nodelay on, tcp_nopush off.

最后通过在ngx_lua里增加调试代码, 发现websocket客户端socket的TCP_NODELAY是没设的
int nodelay;
socklen_t optlen = sizeof(nodelay);
ngx_connection_t *c = u->peer.connection;
 
getsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, &optlen)

ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                  "lua tcp socket nodelay: %d", nodelay)

而在ngx_lua的ngx.req.socket实现里会显式地检查并设置TCP_NODELAY

如下测试用例可重现该问题:
http {

    tcp_nopush     off;
    tcp_nodelay    on;
    (省略部分配置)

    server {
    
          listen 8080;
          (省略部分配置)
    
          location /ws {
              content_by_lua '
                  local server, err = resty.websocket.server:new()
                  while true do
                      local data, opcode, err = server:recv_frame()
                      if not data or opcode == "close" then
                          break
                      else
                          ngx.log(ngx.ERR, "recv " .. opcode .. ": " .. ngx.now())
                          if opcode == "ping" then
                              server:send_pong()
                              ngx.log(ngx.ERR, "send pong: " .. ngx.now())
                          end
                      end
                  end
              ';
          }
      
          location /foo {
              content_by_lua '
                  local client, err = resty.websocket.client:new()
                  client:connect("ws://127.0.0.1:8080/ws")
                  client:send_text("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
                  ngx.log(ngx.ERR, "send text: " .. ngx.now())
      
                  local _, err = client:send_ping()
                  ngx.log(ngx.ERR, "send ping " .. (err and err or "") .. " : " .. ngx.now())
                  local data, opcode, err = client:recv_frame()
                  ngx.log(ngx.ERR, "recv " .. (opcode and opcode or err) .. ": " .. ngx.now())
      
                  client:close()
              ';
          }
    }
}


执行curl http://127.0.0.1:8080/foo 抓包或查看日志均可发现明显的40ms左右的延时

麻烦其它同学也确认一下这个问题, 我稍后再提交补丁.

Yichun Zhang (agentzh)

unread,
Aug 17, 2014, 6:01:57 PM8/17/14
to openresty
Hello!

2014-08-17 0:23 GMT-07:00 aaashun:
> 本周测试websocket时发现一个简单的ping服务端要40ms左右才收到, 40ms是一个很有代表意义的延时.
> nginx.conf里的设置是tcp_nodelay on, tcp_nopush off.
>

多谢你的报告和测试用例!已经在 git 仓库里修正了此问题:

https://github.com/openresty/lua-nginx-module/commit/3acb8dd

Thanks!
-agentzh

aaashun

unread,
Aug 17, 2014, 9:47:45 PM8/17/14
to open...@googlegroups.com
非常感谢!
Reply all
Reply to author
Forward
0 new messages