SLB訪問日誌分析:基於客戶端來源和HTTP狀態碼的實踐

摘要: 阿里雲負載均衡SLB可以對多臺雲服務器(ECS)進行流量分發,支持TCP的四層負載均衡和基於HTTP/HTTPS的七層負載均衡。使用SLB可以降低單臺ECS異常時對業務的衝擊,提升系統可用性。同時,結合彈性伸縮服務(ESS)動態擴容、縮容後端服務器可以快速應對業務流量的變化。

阿里雲負載均衡SLB可以對多臺雲服務器(ECS)進行流量分發,支持TCP的四層負載均衡和基於HTTP/HTTPS的七層負載均衡。使用SLB可以降低單臺ECS異常時對業務的衝擊,提升系統可用性。同時,結合彈性伸縮服務(ESS)動態擴容、縮容後端服務器可以快速應對業務流量的變化。

SLB七層訪問日誌內容豐富,提供近30個字段,例如:收到請求的時間、客戶端的IP地址、處理Latency、請求URI、後端RealServer(阿里雲ECS)地址、返回狀態碼等。在您開啓SLB七層訪問日誌功能後,SLB會記錄對應實例上所有訪問日誌到日誌服務。本文以兩個主題向大家介紹如何通過日誌服務來發掘SLB訪問日誌背後蘊含的一些價值。

請求從哪裏來

這是一個關於client_ip的問題,直接看訪問日誌的client_ip字段就可以回答。但有時會發現client_ip總是那麼幾個值,直覺告訴我們不大對勁:

一個客戶端的請求從最初的ip到SLB負載均衡,如果不經過代理,那麼client_ip記錄的就是原始客戶端ip。而假如請求經過proxy多次轉發,這種情況下訪問日誌記錄的client_ip就不能真實反應請求來源了。

好在SLB訪問日誌中有另兩個字段可以幫助我們解決真實client_ip問題:

  • http_x_forwarded_for,取自HTTP擴展頭X-Forwarded-For字段,是RFC7293標準。假設客戶端在client_0發出請求,到達服務端之前依次經過了三個代理proxy_1、proxy_2、proxy_3,其中proxy_3直連負載均衡器,那麼proxy_3會在X-Forwarded-For上追加proxy_2的ip表示是在替proxy_2轉發請求。這樣多層級聯後形成一個用逗號連接的字符串"client_0_ip,proxy_1_ip,proxy_2_ip",字符串中的第一個即是原客戶端ip。

  • http_x_real_ip,取自HTTP自定義頭X-Real-IP字段,非正式標準但在業內普遍使用。在各層代理始終堅持記錄原始客戶端ip的前提下,這是最方便且正確的取值。

值得注意的是,X-Forwarded-For和X-Real-IP字段都有可能出現不準確的情況,感興趣的同學可以讀一下這篇文章:HTTP請求頭中的X-Forwarded-For。

本文按照X-Real-IP優先策略計算真實的請求來源ip,算法用如下決策樹來表達:

當http_x_forwarded_for、http_x_real_ip字段取值爲字符串"-"時,表示該字段值不是有效內容。那麼通過SQL的case/when語法把上圖的計算方法翻譯如下:

real_client_ip是通過算法得到的優化版真實客戶端ip:

在real_client_ip基礎上,可以使用日誌服務IP地理函數計算訪問來源的地理(國家、省市、運營商、經緯度)信息。例如按照省維度統計PV分佈:

HTTP狀態碼說明了什麼

408 Request Timeout

現象

客戶端請求部署在SLB上的服務,但經常出現網絡超時情況。

排查過程

首先用SQL統計是否有異常的狀態碼:

not (status : 200) | select status, count(*) as pv group by status order by pv desc

分析發現在最近15分鐘的訪問日誌中有些408返回的請求:

關於408狀態碼,它表示服務端在一定時間內沒有收到完整的請求,這個時候服務端決定不再等待,在響應中將Connection首部值設置爲close並主動關閉連接。

發生408錯誤的時候,表現爲Request Timeout。最大可能的兩個原因有:客戶端沒有在超時時間內把數據包發到服務端;或者是因爲服務端負載很重,沒有及時處理請求。如果通過監控可以排除服務端負載原因,那麼可以將更多關注點轉移到客戶端身上。

統計408狀態的client_ip來源:

status : 408 | select client_ip, count(*) as pv group by client_ip order by pv desc

如果client_ip集中在幾個特定來源上,那麼,個別客戶端網絡流量導致問題的可能性就比較大。

同時,查看408狀態碼的日誌發現,異常請求的upstream_addr、upstream_status都沒有記錄,這說明請求沒有到達後端real server。這個時候可以認爲,客戶端問題導致網絡超時的可能性是很大了。

接下來,就請到客戶端上查看網路監控或抓包調查吧。

499 Client Closed Request

現象

SLB負載均衡上的流量出現下跌,同時後端服務器上沒有看到5xx錯誤。

排查過程

經典開局,先看異常狀態碼分佈,但這次我們懷疑是499導致的:

499狀態碼錶示服務端Nginx正在處理請求過程中,客戶端主動關閉了連接。

通過異常的訪問日誌加以印證,upstream_addr記錄了請求在real server上進行處理,但是沒有記錄響應的後端狀態碼upstream_status,說明後端服務器沒有完成請求的處理。並且,整個請求的處理時間request_time用了10秒多,也許正是因爲長時間的等待導致用戶停止了下載任務。

原文鏈接


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章