問題的現象:nginx
客戶端登陸平臺服務器後常常掉線。後端
排查階段1:服務器
首先常規檢查,磁盤容量沒有問題、load average很低、cpu、mem使用率都不高、平臺各服務配置、策略路由都反覆檢查過好幾遍均沒有問題。socket
因爲客戶端首先是經過nginx接入,因此查看nginx日誌文件。此時發現nginx天天生成的日誌文件大小將近有10G。tcp
經過對日誌進行分析得出非高峯時段對nginx中某個接口的每秒請求超過1200次。性能
對比使用平臺的用戶數(日均活躍用戶400人左右),對該接口每秒1200次的請求顯然是不正常的,但仍在nginx的承受範圍內。spa
同一時段,觀察到nginx所在服務器對後端服務器的轉發常常超時,經過抓包發現轉發包並無可以發送(後端服務器也沒有收到),懷疑nginx所在服務器鏈接資源可能存在問題。線程
使用ss -s命令查看發現,存在大量的timewait狀態的socket鏈接,而且ports已經達到了系統設置的上限。日誌
查閱相關資料,因爲nginx使用短連接,所以在高頻請求下會產生大量的timewait狀態的socket鏈接、佔用系統端口資源。接口
臨時解決方法:
放大系統端口數量-如修改sysctl中net.ipv4.ip_local_port_range = 1024 65000
設置端口回收-修改sysctl中net.ipv4.tcp_tw_recycle = 1
但這只是治標不治本,時間一長端口仍然會被佔滿。
此後通過平臺業務開發的修改業務代碼,將對nginx請求數下降到了每秒100次如下,上述端口資源被佔滿的問題完全解決。
排查階段2:
然而就在上述問題解決後沒多久咱們就發現客戶端掉線的問題依然存在,只是掉線頻率降低了一些。
因爲沒有更好的排查手段,依然只能經過抓包,發現客戶端到平臺服務器有丟包現象。
ifconfig查看網卡信息發現RX packets中有大量的dropped包;
ethtool查看網卡信息Supported link modes: 100baseT/Full,即百兆網卡,所以懷疑是網卡性能不足。
因爲該服務器是運行在kvm上的虛擬機,當時在配置虛擬機網卡時device model選擇的默認Hypervisor default推測爲百兆網卡,所以在虛擬機控制檯中將網卡模型調整爲e1000(千兆網卡)。
調整事後RX packets 再也不出現dropped包
排查階段3:
然而問題並無獲得緩解,掉線依舊。疑點是nginx所在服務器ping後端服務器丟包嚴重,但緣由不明。
你們一籌莫展,只好請大拿出馬。
大拿終究是大拿,不久就發現了問題:雖然load average的值很低,可是其中一個cpu的hi(硬中斷)很高,接近滿負荷。
經過查看/proc/interrupts,發現該cpu已被網卡中斷拖垮,懷疑是虛擬機配置的網卡和cpu性能不足。
所以再次在虛擬機控制檯中修改網卡模型爲virtio(這個模型性能最好);調整cpu模型:copy host CPU configuration,調整pinning儘可能使得與其餘虛擬機不一樣時佔用相同的物理cpu。
解決結果:
經過上述調整,最終完全解決了客戶端掉線問題。
後記:
修改sysctl中net.ipv4.tcp_tw_recycle = 1雖然能夠提tpc鏈接回收效率,但會對鏈接會形成一些影響,致使鏈接效率變慢。所以不建議啓用該配置。
附:
top -d 1
top -Hp 進程號
strace -p 線程號
pstack 線程號