SLB访问日志分析:基于客户端来源和HTTP状态码的实践
摘要:?阿里云負(fù)載均衡SLB可以對多臺云服務(wù)器(ECS)進(jìn)行流量分發(fā),支持TCP的四層負(fù)載均衡和基于HTTP/HTTPS的七層負(fù)載均衡。使用SLB可以降低單臺ECS異常時對業(yè)務(wù)的沖擊,提升系統(tǒng)可用性。同時,結(jié)合彈性伸縮服務(wù)(ESS)動態(tài)擴(kuò)容、縮容后端服務(wù)器可以快速應(yīng)對業(yè)務(wù)流量的變化。
阿里云負(fù)載均衡SLB可以對多臺云服務(wù)器(ECS)進(jìn)行流量分發(fā),支持TCP的四層負(fù)載均衡和基于HTTP/HTTPS的七層負(fù)載均衡。使用SLB可以降低單臺ECS異常時對業(yè)務(wù)的沖擊,提升系統(tǒng)可用性。同時,結(jié)合彈性伸縮服務(wù)(ESS)動態(tài)擴(kuò)容、縮容后端服務(wù)器可以快速應(yīng)對業(yè)務(wù)流量的變化。
SLB七層訪問日志內(nèi)容豐富,提供近30個字段,例如:收到請求的時間、客戶端的IP地址、處理Latency、請求URI、后端RealServer(阿里云ECS)地址、返回狀態(tài)碼等。在您開啟SLB七層訪問日志功能后,SLB會記錄對應(yīng)實例上所有訪問日志到日志服務(wù)。本文以兩個主題向大家介紹如何通過日志服務(wù)來發(fā)掘SLB訪問日志背后蘊含的一些價值。
請求從哪里來
這是一個關(guān)于client_ip的問題,直接看訪問日志的client_ip字段就可以回答。但有時會發(fā)現(xiàn)client_ip總是那么幾個值,直覺告訴我們不大對勁:
一個客戶端的請求從最初的ip到SLB負(fù)載均衡,如果不經(jīng)過代理,那么client_ip記錄的就是原始客戶端ip。而假如請求經(jīng)過proxy多次轉(zhuǎn)發(fā),這種情況下訪問日志記錄的client_ip就不能真實反應(yīng)請求來源了。
好在SLB訪問日志中有另兩個字段可以幫助我們解決真實client_ip問題:
- http_x_forwarded_for,取自HTTP擴(kuò)展頭X-Forwarded-For字段,是RFC7293標(biāo)準(zhǔn)。假設(shè)客戶端在client_0發(fā)出請求,到達(dá)服務(wù)端之前依次經(jīng)過了三個代理proxy_1、proxy_2、proxy_3,其中proxy_3直連負(fù)載均衡器,那么proxy_3會在X-Forwarded-For上追加proxy_2的ip表示是在替proxy_2轉(zhuǎn)發(fā)請求。這樣多層級聯(lián)后形成一個用逗號連接的字符串"client_0_ip,proxy_1_ip,proxy_2_ip",字符串中的第一個即是原客戶端ip。
- http_x_real_ip,取自HTTP自定義頭X-Real-IP字段,非正式標(biāo)準(zhǔn)但在業(yè)內(nèi)普遍使用。在各層代理始終堅持記錄原始客戶端ip的前提下,這是最方便且正確的取值。
值得注意的是,X-Forwarded-For和X-Real-IP字段都有可能出現(xiàn)不準(zhǔn)確的情況,感興趣的同學(xué)可以讀一下這篇文章:HTTP請求頭中的X-Forwarded-For。
本文按照X-Real-IP優(yōu)先策略計算真實的請求來源ip,算法用如下決策樹來表達(dá):
當(dāng)http_x_forwarded_for、http_x_real_ip字段取值為字符串"-"時,表示該字段值不是有效內(nèi)容。那么通過SQL的case/when語法把上圖的計算方法翻譯如下:
select (casewhen http_x_real_ip = '-' then (casewhen http_x_forwarded_for = '-' then client_ipwhen split_part(http_x_forwarded_for, ',', 1) = '-' then client_ipelse split_part(http_x_forwarded_for, ',', 1) end)else http_x_real_ipend) as real_client_ipreal_client_ip是通過算法得到的優(yōu)化版真實客戶端ip:
在real_client_ip基礎(chǔ)上,可以使用日志服務(wù)IP地理函數(shù)計算訪問來源的地理(國家、省市、運營商、經(jīng)緯度)信息。例如按照省維度統(tǒng)計PV分布:
HTTP狀態(tài)碼說明了什么
408 Request Timeout
現(xiàn)象
客戶端請求部署在SLB上的服務(wù),但經(jīng)常出現(xiàn)網(wǎng)絡(luò)超時情況。
排查過程
首先用SQL統(tǒng)計是否有異常的狀態(tài)碼:
not (status : 200) | select status, count(*) as pv group by status order by pv desc分析發(fā)現(xiàn)在最近15分鐘的訪問日志中有些408返回的請求:
關(guān)于408狀態(tài)碼,它表示服務(wù)端在一定時間內(nèi)沒有收到完整的請求,這個時候服務(wù)端決定不再等待,在響應(yīng)中將Connection首部值設(shè)置為close并主動關(guān)閉連接。
發(fā)生408錯誤的時候,表現(xiàn)為Request Timeout。最大可能的兩個原因有:客戶端沒有在超時時間內(nèi)把數(shù)據(jù)包發(fā)到服務(wù)端;或者是因為服務(wù)端負(fù)載很重,沒有及時處理請求。如果通過監(jiān)控可以排除服務(wù)端負(fù)載原因,那么可以將更多關(guān)注點轉(zhuǎn)移到客戶端身上。
統(tǒng)計408狀態(tài)的client_ip來源:
status : 408 | select client_ip, count(*) as pv group by client_ip order by pv desc如果client_ip集中在幾個特定來源上,那么,個別客戶端網(wǎng)絡(luò)流量導(dǎo)致問題的可能性就比較大。
同時,查看408狀態(tài)碼的日志發(fā)現(xiàn),異常請求的upstream_addr、upstream_status都沒有記錄,這說明請求沒有到達(dá)后端real server。這個時候可以認(rèn)為,客戶端問題導(dǎo)致網(wǎng)絡(luò)超時的可能性是很大了。
接下來,就請到客戶端上查看網(wǎng)路監(jiān)控或抓包調(diào)查吧。
499 Client Closed Request
現(xiàn)象
SLB負(fù)載均衡上的流量出現(xiàn)下跌,同時后端服務(wù)器上沒有看到5xx錯誤。
排查過程
經(jīng)典開局,先看異常狀態(tài)碼分布,但這次我們懷疑是499導(dǎo)致的:
499狀態(tài)碼表示服務(wù)端Nginx正在處理請求過程中,客戶端主動關(guān)閉了連接。
通過異常的訪問日志加以印證,upstream_addr記錄了請求在real server上進(jìn)行處理,但是沒有記錄響應(yīng)的后端狀態(tài)碼upstream_status,說明后端服務(wù)器沒有完成請求的處理。并且,整個請求的處理時間request_time用了10秒多,也許正是因為長時間的等待導(dǎo)致用戶停止了下載任務(wù)。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的SLB访问日志分析:基于客户端来源和HTTP状态码的实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你只差这两步 | 将Sentinel 控
- 下一篇: 机器学习和数据科学领域必读的10本免费书