前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >记一次线上超时问题的发现、排查、定位以及解决过程

记一次线上超时问题的发现、排查、定位以及解决过程

作者头像
高性能架构探索
发布于 2022-08-25 08:21:36
发布于 2022-08-25 08:21:36
87000
代码可运行
举报
文章被收录于专栏:技术随笔心得技术随笔心得
运行总次数:0
代码可运行

你好,我是雨乐!

在上一篇文章问题解决了,我却不知道原因中提到,最近从性能、监控方面对引擎进行优化,这不,监控刚上了,就发现了一个很严重的问题--超时

今天,借助此文,分享下该问题的发现、排查以及解决过程!

业务背景

在广告业务中,分为效果广告、KA广告以及三方广告等。效果广告和KA广告一般都仅限于内网,也就是说在内网中通过RPC进行访问,而三方广告,则需要访问外网,因为外网环境以及每家三方广告主的处理能力不同,导致性能不同。本次的超时就是针对的某个三方广告主。

本次针对三方的业务监控中,包括对三方广告主的请求数、返回数、qps、rt等指标。

收到报警

增加了监控的业务上线后,根据引擎监控系统来查看三方的基础数据监控,如下:

通过上述图表,看了下平均rt等业务指标,一切正常。开始着手配置超时等监控报警指标。鉴于业务的重要性,配置了邮件告警和短信告警两种,配置完成后,一键生效。结果,过了没几分钟,就收到了告警。

看到超时这么多,第一时间先ping下,看看网络间耗时咋样,结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
64 bytes from 114.67.237.131: icmp_seq=1 ttl=49 time=7.13 ms
64 bytes from 114.67.237.131: icmp_seq=2 ttl=49 time=6.37 ms
64 bytes from 114.67.237.131: icmp_seq=3 ttl=49 time=6.10 ms
64 bytes from 114.67.237.131: icmp_seq=4 ttl=49 time=6.07 ms
64 bytes from 114.67.237.131: icmp_seq=5 ttl=49 time=6.04 ms
64 bytes from 114.67.237.131: icmp_seq=6 ttl=49 time=6.07 ms
64 bytes from 114.67.237.131: icmp_seq=7 ttl=49 time=6.03 ms
64 bytes from 114.67.237.131: icmp_seq=8 ttl=49 time=6.09 ms
64 bytes from 114.67.237.131: icmp_seq=9 ttl=49 time=6.11 ms
64 bytes from 114.67.237.131: icmp_seq=10 ttl=49 time=6.03 ms
64 bytes from 114.67.237.131: icmp_seq=11 ttl=49 time=6.07 ms

网络很稳定,看来跟网络没关系,只能通知对方。

双方沟通

跟对方反馈其rt超时很严重后,对方第一反应是内部有些广告主太耗时,于是其关闭了超时严重的广告主,然后让我这边继续观察。

待对方关闭耗时长的广告主后,重新打开监控报警(之前因为报警太频繁,暂时关闭了报警),然后没有几分钟,报警又又又来了。

赶紧在群里跟对方反馈,对方也是一脸懵逼,双方开始一起排查问题,毕竟没人跟钱过不去😁

为了便于尽快发现,在测试环境尝试将超时时间设置为2s,然后模拟发送请求,果不其然,超时。。。

看了对方的反馈,对方在服务内部也设置了超时,如果200ms内没有得到有效广告,则返回,也就是说对方也做了200ms的超时控制,很奇怪。。。

在测试环境将超时时间设置为50s,仍然有超时现象。。。

对接群沟通多少有点影响到别人,于是勾搭了对方的技术,开始私聊(此处开始甩锅模式)

不过,甩锅归甩锅,问题还得解决。开始尝试使用curl来分析各个阶段的耗时:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
curl  -o /dev/null -s -w %{time_namelookup}::%{time_connect}::%{time_starttransfer}::%{time_total}::%{speed_download}"\n" --data-binary @req.dat https://www.baidu.com

输出结果如下:

从上述结构可以看出,在time_starttransfe阶段,也就是说对方业务处理结果仍然会出现2s耗时,问题复现。

业务代码

虽然该模块的核心代码在线上稳定运行了5年多,但是为了保险起见,还是得再分析下,免得再遗漏了某个分支条件,导致这种现象发生。

一般情况下,log是最直接也是最有效的方式,于是在每个步骤每个运行函数中加了日志,然后编译、运行,使用之前的测试case重新发送请求。分析日志,一切都在预期内,看来业务代码没问题,只能通过其它方式进行排查了。

线上抓包

既然业务代码没问题,那就只能通过tcpdump抓包来分析了,然后经过wireshark解析后,结果如下:

从上面抓包结果来看,在序号为6的位置,对方返回了http 204,然后又重新手动发了一次curl请求,在序号10的时候,对方又返回了http 204(从发送请求到收到对方响应耗时38ms),但是奇怪的时候,在后面50s后,client端(发送方)开发发送FIN请求关闭连接,从代码逻辑来分析,是因为超时导致的关闭连接。

从抓包现象只能得出上述结论,没什么有用的结论,看来只能通过其它方式继续分析。

同类对比

既然抓包都不能得到有用的结论,那就只能通过与其它家正常返回的做对比,看看能不能得到有用结论。

通过修改业务代码,输出http相关信息,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
curl_easy_setopt(handle_, CURLOPT_VERBOSE, 1L);

编译,运行,发起curl请求。

正常三方返回如下:

而超时的该家返回如下:

通过对比上述两家的区别,发现超时的该家较正常的三方返回,多了Content-LengthContent-Type等字段,那么有没有可能跟这几个字段的返回有关呢?

问题解决

让对方在其测试环境,在没有广告返回的时候,将这几个字段去掉。然后我这边重新发起curl请求。。。

然后发起curl请求,一切正常,在超时范围内返回。wrk压测,平均rt符合预期,看来问题就在这。

跟对方沟通后,对方修改代码,然后着手上线,上线后结果如下:

效果很明显,看来就是这个原因导致,超时问题解决了,收入也就蹭蹭地往上涨了😃。

分析原因

既然问题已经解决了,多少得知道原因吧,于是在搜索引擎上输入http 204 Content-Length hang,找到了有用信息,如下:

看来wget之前也存在此类问题,于是继续搜索标准,输出如下:

The presence of a message body in a response depends on both the request method to which it is responding and the response status code (Section 3.1.2). Responses to the HEAD request method (Section 4.3.2 of [RFC7231]) never include a message body because the associated response header fields (e.g., Transfer-Encoding, Content-Length, etc.), if present, indicate only what their values would have been if the request method had been GET (Section 4.3.1 of [RFC7231]). 2xx (Successful) responses to a CONNECT request method (Section 4.3.6 of [RFC7231]) switch to tunnel mode instead of having a message body. All 1xx (Informational), 204 (No Content), and 304 (Not Modified) responses do not include a message body. All other responses do include a message body, although the body might be of zero length.

深入源码

从上节标准可以看出,在http 204、304的时候,不允许返回Content-Length,那么如果返回了,libcurl又是如何处理的呢?

于是在curl的issue上进行了关键字搜索,得到了如下结果:

看来已经有人提过这个问题了,于是看了下当前线上libcurl的源码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
switch(k->httpcode) {
        case 204:
           /* (quote from RFC2616, section 10.2.5): The server has
            * fulfilled the request but does not need to return an
            * entity-body ... The 204 response MUST NOT include a
            * message-body, and thus is always terminated by the first
            * empty line after the header fields. */
           /* FALLTHROUGH */
                case 304:
           /* (quote from RFC2616, section 10.3.5): The 304 response
            * MUST NOT contain a message-body, and thus is always
            * terminated by the first empty line after the header
            * fields.  */
           if(data->set.timecondition)
             data->info.timecond = TRUE;
           k->size=0;
           k->maxdownload=0;
           k->ignorecl = TRUE; /* ignore Content-Length headers */
           break;

线上使用的版本果然没有处理此种情况,再跟线上做对比,改动如下:

好了,问题已经解决,原因也已经找到,毕竟不是大bug,为了稳妥起见,还是不升级了,以稳定为主,谁知道升级后又会出现什么意想不到的问题呢😁

结语

该问题从发现到解决,大概用了2天的时间。其实,从文章的目录结构就能发现,整个问题发现以及解决过程跟文章目录结构一致:收到报警->双方沟通->业务代码->线上抓包->同类对比->问题解决->原因分析->深入源码

好了,今天的文章就到这,我们下期见!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 高性能架构探索 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【转】记一次线上超时问题的发现、排查、定位以及解决过程
https://blog.csdn.net/m0_73311735/article/details/131806588
阿东
2023/07/21
2860
【转】记一次线上超时问题的发现、排查、定位以及解决过程
找到你常浏览网站中的 201/204/206 状态码请求
示例二: 知乎为 Delete 请求的状态码设置为 204,以下请求代表取消关注某人。
山月
2022/11/02
2.9K0
找到你常浏览网站中的 201/204/206 状态码请求
我找到了一个快速定位SpringBoot接口超时问题的神器!
松哥最近正在录制 TienChin 项目视频~采用 Spring Boot+Vue3 技术栈,里边会涉及到各种好玩的技术,小伙伴们来和松哥一起做一个完成率超 90% 的项目,戳戳戳这里-->TienChin 项目配套视频来啦。 ---- 本文地址:https://juejin.cn/post/7140462361759973384 背景 公司有个渠道系统,专门对接三方渠道使用,没有什么业务逻辑,主要是转换报文和参数校验之类的工作,起着一个承上启下的作用。 最近在优化接口的响应时间,优化了代码之后,但是时
江南一点雨
2022/09/20
1.5K0
我找到了一个快速定位SpringBoot接口超时问题的神器!
关于Linux 网络抓包的一些笔记整理
这世界的存在完全只是就它对一个其他事物的,一个进行 "表象者" 的关系来说的,这个进行 "表象者" 就是人自己 -----《作为意志和表象的世界》(第一篇 世界作为表象初论)
山河已无恙
2023/08/21
4140
关于Linux 网络抓包的一些笔记整理
两条命令找出第三方接口问题点
这几天疲于救火,火气有点儿大,今早领导在群里@我了下,说第三方接口反馈我们的网络有些问题。搞得我一头雾水, 我首先问清了事情的原委,原来我们这边某个应用调用了第三方接口,但是应用这边时不时的会甩出那么几条错误,而且近期比较多。这不问题一多,大家就紧张了。为了自证清白,我不得不拿起武器自卫。
三杯水Plus
2020/06/11
3700
如果设置Redis客户端的超时时长?
客户端的超时时长分连接超时和读写超时,如果是基于hiredis的实现,则读写超时是合在一起的,同一参数控制。
一见
2019/08/30
4.1K0
干货 | Web开发必备技能:网络不通,3指令精准定位故障点
做Web开发必不可少与网络连接打交道,就是运维也整天都是301,302,401,403,404,500,502,503。见的多了,你都会烂熟于胸。让我们采用自上而下的方法,来测试Internet连接并对其进行故障排除。
程序员小助手
2020/05/14
6990
Linux高级流量控制tc使用
在做MHA测试的时候,有一个重要的环节就是测试MHA Manager节点和Master节点的网络情况,如果产生了抖动,那么MHA本身提供了一个参数secondary_check来保证,但是如果你的部署环境中是一主一从的话,这个参数就不会起作用了,因为latest slave和oldest slave是同一个库,简单来说,连不上就是连不上了,至于切还是不切,这个还不好说。我们测试的场景下,有时候切,有时候不切。所以我们原本测试的MHA0.57版本就降级为了0.56,仔细测试发现,其实也存在这样的问题,综合再三
jeanron100
2018/03/22
4.7K0
openresty替换线上nginx之ipv6功能测试
我们最近的一个需求是用openresty替换线上的nginx,而线上nginx是开启了支持ipv6的。那么我们openresty也需要在开发环境测试,看看能不能支持ipv6.
低级知识传播者
2023/08/30
8570
openresty替换线上nginx之ipv6功能测试
linux定位问题常用命令
如果要显示所有的网络接口,包含在线(up)的或下线(down)的,使用-a 选项。
聂伟星
2020/08/28
2.7K0
Mac安装git,brew出现的问题
然后怀疑是不是因为连接不上github出现的问题 开始测试 结果就是一直超时 就想到是不是hosts出现的问题
河湾欢儿
2020/07/28
16K0
运维分享|测试主机间的连通性方法总结
很多时候,我们需要测试两台或者多台机器的网络策略是否是连通状态。当然,在做系统集成时,这个就更显得尤为重要了。
六月暴雪飞梨花
2023/11/21
1.4K0
运维分享|测试主机间的连通性方法总结
learning:af_packet plugin (2)
最近的vpp-dev邮件中在讨论使用af-packet插件时,创建host接口之后ping功能出现很高的延迟。
dpdk-vpp源码解读
2023/10/28
5731
learning:af_packet plugin (2)
Linux运行有时间限制的命令—timeout命令
timeout是用来控制程序运行的时间,运行指定的命令。如果在指定时间后仍在运行,则杀死该进程。使用timeout命令可以让程序在指定的时间内仍然运行则强制退出。
胡齐
2020/02/25
14.3K0
Ping报文理解mtu拆包依据
注意这里 PING 192.168.10.46 (192.168.10.46) 56(84) bytes of data.
mingjie
2022/05/12
1.3K0
Ping报文理解mtu拆包依据
连接一个 IP 不存在的主机时,握手过程是怎样的?
现在忙完工作,还要一三五学驾照,二四六看家具。有同感的老铁们不要举手,拉到右下角点个"在看"就好了。
haohongfan
2021/07/23
1.1K0
连接一个 IP 不存在的主机时,握手过程是怎样的?
ping, telnet, tcping 命令使用及对比
1. ping 命令 ping 命令只能检查 IP 的连通性或网络连接速度,无法具体到某个端口。
全栈程序员站长
2022/09/09
4.2K1
ping, telnet, tcping 命令使用及对比
利用ICMPv4协议实现一个ping程序
Icmp(Internet Control Message Protocol)协议一般与IP协议结合使用,以便给IP协议提供诊断和控制信息。 Icmp通常被认为是Ip协议的一部分,传输的时候也是被封装在Ip报文内。 我们在判断网络状况时用的ping程序就利用了ICMP协议。接下来先运行系统上的ping程序,用tcpdump抓包查看一下传输的数据。 然后解释一下icmp数据报的各个字段。最后思考一下ping程序的结构,然后用c++实现一个自己的ping程序。
yifei_
2022/11/14
6630
利用ICMPv4协议实现一个ping程序
云网络运维常用命令工具
ping 命令是基于 ICMP 协议来工作的,ICMP全称为 Internet 控制报文协议(Internet Control Message Protocol)。ping 命令会发送一份ICMP回显请求报文给目标主机,并等待目标主机返回ICMP回显应答。因为ICMP协议会要求目标主机在收到消息之后,必须返回ICMP应答消息给源主机,如果源主机在一定时间内收到了目标主机的应答,则表明两台主机之间网络是可达的。除了监测是否可达以外,还可以利用应答时间和发起时间之间的差值,计算出数据包的延迟耗时。
Ching云服务杂论
2020/07/06
5.3K0
Linux 之 ping 命令
原文链接:https://rumenz.com/rumenbiji/linux-ping.html
入门笔记
2021/08/09
11K0
相关推荐
【转】记一次线上超时问题的发现、排查、定位以及解决过程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档