最近針對公司的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,不進行握手操作,不會有任何超時機制,目前新增的超時可以針對這種情況做處理。