一次带宽拉满引发的百分百超时血案!

来自公众号:Gopher指北

偈语: 未经他人苦,莫劝他人善

鏖战两周有余,为了排查线上某接口百分百超时的原因,如今总算有些成果。虽然仍有疑虑但是碍于时间不允许和个人能力问题先做如下总结以备来日再战。

出口带宽拉满

能够发现这个问题实属侥幸。依稀记得这是一个风雨交加的夜晚,这风、这雨注定了今夜的不平凡。果然线上百分百超时的根因被发现了!

image

我们的线上接口需要对外请求,而我们的流出带宽被拉满自然耗时就长因此导致超时。当然这都是结果,毕竟中间过程的艰辛已经远远超出老许的文字所能描述的范围。

反思

结果有了,该有的反思仍旧不能少。比如流出带宽被拉满为什么没有提前预警!无论是自信带宽足够还是经验不足都值得老许记上一笔。

而在带宽问题被真正发现之前,老许内心对带宽其实已有所怀疑,但是却没有认真进行验证,只听信了他人的推测导致发现问题的时间被推迟。

httptrace

有时候不得不吹一波Go对http trace的良好支持。老许也是基于此做了一个demo,该demo可以打印http请求各阶段耗时。

image

上述为一次http请求各阶段耗时输出,有兴趣的可去https://github.com/Isites/go-coder/blob/master/httptrace/trace.go拿到源码。

老许对带宽的怀疑主要就是基于此demo中的源码进行线上分析测试给到的推测。

框架问题

本部分更加适合腾讯系的兄弟们去阅读,其他非腾讯系技术可以直接跳过。

我司的框架为TarsGo,我们在线上设置handletimeout为1500ms,该参数主要用于控制某一接口总耗时不超过1500ms,而我们的超时告警均为3s,因此即使带宽已满这个百分百超时告警也不应出现。

为了研究这个原因,老许只好花些零碎的时间去阅读源码,最终发现了TarsGo@v1.1.6handletimeout控制是无效的。

下面看一下有问题的源码:

func (s *TarsProtocol) InvokeTimeout(pkg []byte) []byte {
    rspPackage := requestf.ResponsePacket{}
    rspPackage.IRet = 1
    rspPackage.SResultDesc = "server invoke timeout"
    return s.rsp2Byte(&rspPackage)
}

当某接口总执行时间超过handletimeout时,会调用InvokeTimeout方法告知client调用超时,而上述的逻辑中忽略了IRequestId的响应,这就导致client收到响应包时无法将响应包和某次的请求对应起来,从而导致客户端一直等待响应直至超时。

最终修改如下:

func (s *TarsProtocol) InvokeTimeout(pkg []byte) []byte {
    rspPackage := requestf.ResponsePacket{}
    //  invoketimeout need to return IRequestId
    reqPackage := requestf.RequestPacket{}
    is := codec.NewReader(pkg[4:])
    reqPackage.ReadFrom(is)
    rspPackage.IRequestId = reqPackage.IRequestId
    rspPackage.IRet = 1
    rspPackage.SResultDesc = "server invoke timeout"
    return s.rsp2Byte(&rspPackage)
}

后来老许在本地用demo验证handletimeout终于可以控制生效。当然本次修改老许已经在github上面提交issue和pr,目前已被合入master。相关issue和pr如下:

https://github.com/TarsCloud/TarsGo/issues/294

https://github.com/TarsCloud/TarsGo/pull/295

仍有疑虑

到这里,事情依然没有得到完美的解决。

image

上图为我们对外部请求做的最大耗时统计,毛刺严重且耗时简直不符合常理。图中标红部分耗时约为881秒,而实际上我们在发起http请求时均做了严格的超时控制,这也是令老许最为头疼的问题,这几天脸上冒的痘都是为它熬夜的证明。

更加令人惊恐的事情是,我们将官方的http替换为fasthttp后,毛刺没有了!老许自认为对go的http源码还有几分浅薄的理解,而残酷的现实简直令人怀疑人生。

到目前,老许再次简阅了一遍http的源码,仍未发现问题,这大概率会成为一桩悬案了,还望各位有经验的大佬分享一二,至少让这篇文章有始有终。

替换fasthttp时还未发现带宽被拉满

美好愿景

最后,别无他言,直接上图!

image
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容