1. 程式人生 > >後臺常見問題定位及應對指南

後臺常見問題定位及應對指南

recycle 一是 roc 打開 建立連接 post 程序 markdown 日誌

目錄

  • 前言

  • 常規錯誤

  • 短連接之禍

  • IO之禍

  • 總結


說明

由於個人水平有限,總結歸納的時候可能存在錯誤,還望指出。

前言


後臺故障是一個很寬泛的概念,本文有些標題黨了,本文只是針對如下幾點簡單分析

  • 日誌規範
  • tcp短連接使用過多
  • io頻繁

程序邏輯錯誤或是發布變更引起的故障之類的不在討論範圍內。後臺服務出現故障時大多數情況下都會伴隨著cpu爆滿,或者內存不足,或者網卡塞滿,io頻繁等情況,故障的定位少不了神兵利器,這裏有一篇linux下常用工具的介紹:後臺故障&性能分析常用工具。

常規錯誤

這裏把能通過日誌定位到的錯誤視為常規錯誤。比如說某個調用失敗會導致該次請求失敗,我們可以通過寫日誌,將關鍵信息都記錄下來,方便之後的問題定位。寫日誌其實也有一些要註意的點

  • 避免無效的信息,控制好日誌的量和級別,日誌寫多了影響性能
  • 關鍵信息要記錄全,如某個調用失敗了,不能只打印一句 xxx Fail,而是要把對應的錯誤碼,錯誤信息,該調用的關鍵參數打印出來,方便後續問題定位。

短連接之禍

tcp連接在關閉的時候,主動關閉的一方將會經歷time_wait狀態,一旦端口消耗速度持續大於端口回收速度,自然會造成端口不夠用。但是話說回來,端口不夠用這種情況只會出現在主動發起連接的那一端,因為listen -> accept 並不需要分配端口。

定位方法

使用 ss -s 命令,查看各狀態的tcp連接數,如果time_wait狀態過多且端口消耗速度持續增長,就得留點神了
另外對於服務端來說,有時我們會想要定位連接主要來自哪些ip,可以通過ss配合awk及uniq,sort等命令得到結論,如:

ss -n |grep ESTAB | awk ‘{ print $5 }‘ | awk -F: ‘{ print $1 }‘ | sort | uniq -c | sort -rn

可以得到每個ip的連接數的排序

應對方案

  • 1 放開port range,既然端口不夠用,那麽我們就加大端口數,使用如下命令可以得到當前系統向外建立連接時可用的端口範圍

    cat /proc/sys/net/ipv4/ip_local_port_range

    通過如下指令可以設置端口範圍,如

    echo "1024 61000" > /proc/sys/net/ipv4/ip_local_port_range

    但是調整port range後可能會出現某些服務無法重啟,這是因為range調大之後,原先的服務監聽的端口被系統分配出去了,這個時候可以把相關服務所綁定的端口設置到保留端口中,如

    echo "10000,20000" > /proc/sys/net/ipv4/ip_local_reserved_ports
  • 2 加快time_wait回收速度
    通過如下命令可以打開time_wait快速回收,recycle需要配合timestapms一起使用,不過timestamps是默認就打開的,開啟後在3.5*RTO時間內回收

    echo "1" > /proc/sys/net/ipv4/tcp_tw_recycle
    若timestapms關閉了,則將其打開
    echo "1" > /proc/sys/net/ipv4/tcp_timestamps
  • 3 可以打開tcp_tw_resue選項,reuse也需要配合timestapms一起使用,開啟後在1s內回收

    echo "1" > /proc/sys/net/ipv4/tcp_tw_reuse

    註意: 以上的修改都是臨時的,一旦系統重啟又將恢復為默認值,可以通過將這些參數添加到/etc/sysctl.conf文件中,並使用sysctl –p命令使之生效。相關閱讀Linux之TCPIP內核參數優化,TCP連接的狀態與關閉方式,及其對Server與Client的影響,另外nat網絡下,打開tw_recycle將可能導致tcp連接建立錯誤,詳見鏈接tcp_tw_recycle和tcp_timestamps導致connect失敗問題,不過同idc內的服務器之間不存在這個問題,但是還有一個問題,timewait的存在幫我們規避掉了舊連接對新連接的影響,關閉之後,是可能導致舊連接的數據包或fin包到達新連接,或者主動關閉方發送的ack丟包,導致對端仍舊處於last_ack狀態,而主動關閉方快速回收了該socket,且新建連接時,該port被重用,發送syn過去時,將被回復rst,不過同idc內的網絡環境應該是非常良好的,dog微笑臉。最後還可以通過設置SO_LINGER選項,在關閉socket時會非常粗暴的直接發送一個rst報文給對端,從而避免掉timewait狀態。

  • 4 使用長連接+連接池,引入長連接也有一些點需要註意,主要是以下三點
  • 一是對底層服務的負載控制,短連接模式下可以很輕松的實現對底層服務的負載控制,長連接情況要麻煩一點
  • 二是底層服務擴容時,連接池需要感知並調整
  • 三是長連接+連接池技術 如果實現的不好的話本身也可能成為性能瓶頸,最好是能根據請求量動態的調整連接數,少了容易成為性能瓶頸,多了浪費端口,不過一般情況下端口肯定是夠用的。

IO之禍

這個沒什麽好說的,io多了必然給磁盤帶來壓力,由此帶來的io等待時間必然上漲,對於我們的後臺服務而言,io過多基本是由於寫日誌導致。

定位方法

使用vmstat 命令查看當前系統io情況,以及cpu的wa(cpu空轉等待io就緒)所占時間比例。如

vmstat 2

重點觀察bi,bo以及wa項。分別代表塊讀入速度和塊寫入速度以及io等待時間比例。

應對方法

通過/dev/null文件快速關閉日誌,如

ln -s /dev/null xxx.log

關於/dev/null和/dev/zero文件的介紹可以查看鏈接,/dev/null 和 /dev/zero 簡介及對比,關閉日誌只是緊急處理方法,後續還是要優化好寫日誌的邏輯,控制好量和級別。

總結


後臺服務出現性能故障時,可以遵循以下思路去定位(以下內容參考自客廳後臺開發群熊哥的聊天內容)

  • 1 先看vmstat,看io是否高,如是,可關閉日誌,快速方法:ln -s /dev/null xxx.log
  • 2 io不高,再看cpu消耗在用戶態還是內核態,如果是用戶態,通常是觸發了程序bug,可用ltrace定位,快速方法:重啟服務
  • 3 如果內核態cpu高,對tcp類網絡服務,80%原因就是端口耗盡,通過ss -s看端口和time_wait等各個狀態,快速方法:加大port range,打開tw_recycle和tw_reuse

感謝運維們。

後臺常見問題定位及應對指南