「golang」關於TIME_WAIT優化


【問題現象】

項目遺留問題:項目一般用redis作為緩存,並發量突增時很容易出現TCP連接失敗(無可用端口)

【問題分析】

  根據錯誤日志,排查出是連接數達到了最大值,(其實通過 netstat -anp|grep TIME_WAIT|wc -l也可以初略統計出當前的連接數),導致redis緩存無法使用。問題的原因是在於TIME_WAIT數量過大(會占用端口),因為每次連接斷開后都會產生TIME_WAIT,這跟三次握手四次揮手有關,本質上TIME_WAIT是用於優化網絡通信的。

  根據網上大部分的參考意見是修改linux的net.ipv4.tcp_tw_recycle值,說白了就是關閉了這個優化方案,雖然可行,但不建議這樣處理,關閉之后可能會產生其它網絡異常,雖然可能是小概率的。

  這次從產生如此多的TIME_WAIT出發點考慮。很容易發現要不就是沒用連接池,要不就是連接池的參數配置跟項目差異比較大;1、對於redis緩存,使用redisgo自帶的連接池,需配置MaxIdle值;2、對於數據庫,自帶連接池(默認可能未啟用),直接調用SetMaxIdleConns設置MaxIdle值;3、對於http請求,默認沒有連接池,可使用通用的go-commons-pool,通過borrow和return機制使用連接池,如有資源申請,務必記得釋放;4、通過nginx轉發,需在nginx.conf配置文件中增加keep alive配置。

  所有連接池都需關注idle連接數值,這個特別重要,應設置成與項目並發量相近,過低失去緩存意義,過高就是浪費。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com