最近针对公司的goscon网关发了一个PR,新增了握手阶段的超时判定。现在回顾一下Nginx的所有超时判定,看看目前还缺少哪些判定

 

ngx_http_core_module包含的timeout:

client_header_timeout (默认60秒)

client_body_timeout  (默认60秒)

keepalive_timeout   (默认75秒)

lingering_timeout   (默认5秒)

resolver_timeout    (默认30秒)

send_timeout      (默认60秒)

 

上述参数对应的行为如下:

  1. client_header_timeout对应的是客户端发送http请求头的行为
  2. client_body_timeout对应的是客户端发送http消息体的行为
  3. keepalive_timeout对应的是http 1.1协议里的保活时长
  4. lingering_timeout是配合lingering_close使用的,就是说关闭socket前,客户端还有数据发给服务器的话,lingering_close用于设定要不要等客户端继续发,lingering_timeout决定等多久。这里是一个等待-读取-抛弃数据的循环,有可能重复多次,但是每次等待都不会超过lingering_timeout设定的时长
  5. resolver_timeout对应的是域名解析的时长
  6. send_timeout对应的是发送http响应给客户端时的超时。这里对应的是两次写操作之间的时长,经过了send_timeout的时间后,还不能写的话,就关闭连接。

对应到goscon,目前的超时参数,是reuseTimeout和uploadMaxDelay。reuseTimeout会在read/write操作异常的时候生效,度过reuseTimeout时间后,goscon保持的连接对就会被释放,里面的缓存数据都会丢掉。从行为上看,有点类似Nginx的keepalive_timeout。

 

uploadMaxDelay是用在给socket设置读超时上的,只要设置了这个参数(和optUploadMinPacket),每次从socket里读数据都会设置一个deadline。超过deadline后,会返回错误。这里漏了一个写的超时,留了个SetWriteDeadline的接口,但是没有调用。每次写操作也应该有类似的流程,超过delay后write就返回error,Timeout()==True。这个参数类似于Nginx的send_timeout,针对的是两次成功写操作的间隔。缺陷是对方依然可以每次读1个字节,然后等满一次timeout来占用资源。

 

这次goscon新增的握手阶段的超时(handshakeTimeout),类似于client_header_timeout+client_body_timeout+send_timeout,包含了服务器对客户端的一次读,对客户端的一次写。之前只要连上tcp,不进行握手操作,不会有任何超时机制,目前新增的超时可以针对这种情况做处理。