最近QA對線上單模塊進行壓測(非全鏈路壓測),http客戶端 與 thrift服務端的tcp連接總在一段時間被close。
查看服務端日誌顯示 i/o timeout.
最後的結果是: qps過小, 長時間不發送請求, server主動關閉socketredis
thrift框架處理請求僞代碼以下:服務器
//服務端listen for { // 服務端接收一個tcp鏈接請求 client := server.accept() // 獨立啓動一個goroutine處理client後續請求 go fun () { inputTrans := xxx(client) outputTrans := xxx(client) if inputTrans != nil { //return 時, 關閉讀 defer inputTrans.close() } if outputTrans != nil { defer outputTrans.close() //return時, 關閉寫 } //獨立goroutine處理寫結果 (使用channel同步) go func( for { //超時,或者其餘錯誤, return } ) () //for循環: 服務讀取請求 (兩個for循環使用channel同步) for { //超時,或者其餘錯誤, return } }() }
能夠看出,框架
壓測工具,只負責發送請求,通常不讀取請求。
若是使用socket直接連服務器thrift端口,只send數據,不recv數據。可能使得server發送緩衝區滿,發送數據超時。socket
client qps過小,發送請求時間間隔大於server設置的讀超時時間。tcp
這裏不是長鏈接、短鏈接的問題,是server服務器端的一種自我保護機制。
服務器用於接收大量的client請求,若是存在大量的無用鏈接不只會佔用服務器資源,更嚴重的狀況會使得其餘client沒法鏈接服務器的狀況。
能夠使用其餘方法解決:工具
- client和server自定義心跳協議。如secret的發送no-op命令
- 好比redis client, 若是鏈接斷開能夠進行重發一次(先鏈接,再發)