SLB访问日志分析:基于客户端来源和HTTP状态码的实践

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 阿里云负载均衡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总是那么几个值,直觉告诉我们不大对劲:

slb_client_ip_ori

一个客户端的请求从最初的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,算法用如下决策树来表达:

slb_client_ip_algorithm

当http_x_forwarded_for、http_x_real_ip字段取值为字符串"-"时,表示该字段值不是有效内容。那么通过SQL的case/when语法把上图的计算方法翻译如下:

* | select (case
        when http_x_real_ip = '-' then (case
                                        when http_x_forwarded_for = '-' then client_ip
                                        when split_part(http_x_forwarded_for, ',', 1)  = '-' then client_ip
                                        else split_part(http_x_forwarded_for, ',', 1) 
                                        end)
        else http_x_real_ip
        end) as real_client_ip

real_client_ip是通过算法得到的优化版真实客户端ip:

slb_client_ip_real

在real_client_ip基础上,可以使用日志服务IP地理函数计算访问来源的地理(国家、省市、运营商、经纬度)信息。例如按照省维度统计PV分布:

slb_real_ip_province_distribute

基于此的另一个例子,统计真实用户ip下带宽流量、pv:

* | select (case when http_x_real_ip = '-' then (case when http_x_forwarded_for = '-' then client_ip when split_part(http_x_forwarded_for, ',', 1)  = '-' then client_ip else split_part(http_x_forwarded_for, ',', 1) end) else http_x_real_ip end) as real_client_ip, sum(request_length) as request_bytes, sum(body_bytes_sent) as response_bytes, count(1) as pv group by real_client_ip

HTTP状态码说明了什么

408 Request Timeout

现象

客户端请求部署在SLB上的服务,但经常出现网络超时情况。

排查过程

首先用SQL统计是否有异常的状态码:

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

分析发现在最近15分钟的访问日志中有些408返回的请求:

408_status_distribute

关于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。这个时候可以认为,客户端问题导致网络超时的可能性是很大了。

408_upstream

接下来,就请到客户端上查看网路监控或抓包调查吧。

499 Client Closed Request

现象

SLB负载均衡上的流量出现下跌,同时后端服务器上没有看到5xx错误。

排查过程

经典开局,先看异常状态码分布,但这次我们怀疑是499导致的:

client_499

499状态码表示服务端Nginx正在处理请求过程中,客户端主动关闭了连接。

通过异常的访问日志加以印证,upstream_addr记录了请求在real server上进行处理,但是没有记录响应的后端状态码upstream_status,说明后端服务器没有完成请求的处理。并且,整个请求的处理时间request_time用了10秒多,也许正是因为长时间的等待导致用户停止了下载任务。

更多关于SLB七层访问日志分析

  • 文档

负载均衡7层访问日志功能

SLB访问日志分析-文档

SLB访问日志分析-视频

  • 云栖文章

新功能:阿里云负载均衡支持访问日志功能

用好SLB访问日志,做实时可视化分析

相关实践学习
一小时快速掌握 SQL 语法
本实验带您学习SQL的基础语法,快速入门SQL。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
缓存 UED 开发者
HTTP常用状态码详解
HTTP常用状态码详解
|
2月前
|
算法 API UED
基于Gin框架的HTTP接口限速实践
基于Gin框架的HTTP接口限速实践
27 0
|
2月前
|
XML 存储 缓存
四、《图解HTTP》- 状态码
四、《图解HTTP》- 状态码
44 0
|
3月前
|
监控 Android开发 C语言
深度解读Android崩溃日志案例分析2:tombstone日志
深度解读Android崩溃日志案例分析2:tombstone日志
78 0
|
3月前
|
缓存 网络协议 数据库连接
C/S架构中HTTP错误状态码原因分析及解决办法
HTTP(Hypertext Transfer Protocol)是用于在客户端和服务器之间传输数据的协议。当在浏览器或其他HTTP客户端中访问网页时,可能会发生各种访问报错。我们需要根据网页提供的错误状态码分析错误原因,以找到相对应的解决办法。
41 0
|
27天前
|
Prometheus 监控 Kubernetes
Kubernetes 集群监控与日志管理实践
【2月更文挑战第29天】 在微服务架构日益普及的当下,Kubernetes 已成为容器编排的事实标准。然而,随着集群规模的扩大和业务复杂度的提升,有效的监控和日志管理变得至关重要。本文将探讨构建高效 Kubernetes 集群监控系统的策略,以及实施日志聚合和分析的最佳实践。通过引入如 Prometheus 和 Fluentd 等开源工具,我们旨在为运维专家提供一套完整的解决方案,以保障系统的稳定性和可靠性。
|
25天前
|
Prometheus 监控 Kubernetes
Kubernetes 集群的监控与日志管理实践
【2月更文挑战第31天】 在微服务架构日益普及的今天,容器编排工具如Kubernetes已成为部署、管理和扩展容器化应用的关键平台。然而,随着集群规模的扩大和业务复杂性的增加,如何有效监控集群状态、及时响应系统异常,以及管理海量日志信息成为了运维人员面临的重要挑战。本文将深入探讨 Kubernetes 集群监控的最佳实践和日志管理的高效策略,旨在为运维团队提供一套系统的解决思路和操作指南。
23 0
|
1月前
|
存储
Hudi Log日志文件格式分析(一)
Hudi Log日志文件格式分析(一)
25 1
|
1月前
|
缓存 索引
Hudi Log日志文件写入分析(二)
Hudi Log日志文件写入分析(二)
20 1
|
1月前
|
缓存
Hudi Log日志文件读取分析(三)
Hudi Log日志文件读取分析(三)
22 0

热门文章

最新文章

相关产品

  • 日志服务