最近针对公司的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秒)
上述参数对应的行为如下:
-
client_header_timeout
对应的是客户端发送http请求头的行为 -
client_body_timeout
对应的是客户端发送http消息体的行为 -
keepalive_timeout
对应的是http 1.1协议里的保活时长 -
lingering_timeout
是配合lingering_close使用的,就是说关闭socket前,客户端还有数据发给服务器的话,lingering_close用于设定要不要等客户端继续发,lingering_timeout决定等多久。这里是一个等待-读取-抛弃数据的循环,有可能重复多次,但是每次等待都不会超过lingering_timeout设定的时长
-
resolver_timeout
对应的是域名解析的时长 -
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,不进行握手操作,不会有任何超时机制,目前新增的超时可以针对这种情况做处理。