cdn回源源站只吐小包怎么办?

从事cdn传输优化多年,经常能遇到各种奇葩问题。并且cdn金主爸爸们意愿度强势,怼我们永远是一句“为何之前用xx云都没有问题,切量到你这就出问题?”“那我走?” 往往听到这句,就感觉爸爸们下了最后通牒,只能立刻回复到“别走,再给我们一次机会,一定给你满意的答复”。有些问题的排查往往都需要多年的经验累积,有些只在某些特殊的场景才能触发出现,所以想写点什么,避免后来人踩坑。

        

昨天刚要想下班,就遇到了一个这样奇怪的问题。说是某些地区机器出现回源请求特别慢,200KB的数据居然传输了快1分钟了。并且只有回某些源站特别慢,请求别的服务器速率都非常快。这问题场景描述,感觉就是客户源站有问题,换个源站就能正常的传输。客服部的同事也是这么回复客户的,然而客户爸爸一顿输出 “用了某某友商都没有问题..." 赶紧配合复现下场景抓包数据包分析下。好在这问题复现概率非常高,基本每次都复现了。 wireshark一看,源站每次发送都是97字节的小包,还都带push标志,双端协商的mss是1240啊,源站的应用层无数据发送吗?

但是这个工单问题下结论都不能轻率,每次下结论前都需要问自己几个问题,看看这样的结论能否说服自己。

“为啥每次都是97?”——应用层写入每次都只写入97字节,所以都带push标志。

“为什么只在我们这出现,别家厂商不复现?”——无法解释。

所以需要解决为什么每次都发送97字节的问题,进一步看了下我们发送的包。通告的窗口未进行的窗口扩大相乘前,就一直发送的97。似乎看到的问题的希望了,就是我们发送的窗口的扩大因子,对端没有成功处理。

如何快速验证呢?关闭这个窗口扩大因子,echo 0 > /proc/sys/net/ipv4/tcp_window_scaling ,通告的窗口值就不需要进行扩大因子的计算就是原始值。测试了三次,下载速率恢复了。

结论似乎就变成了“源站的内核似乎没有正确处理窗口扩大因子”,只要推动某一端关闭这个window_scaling选项就可以解决问题。传输优化多年,经常发现有些问题,能通过多种方式来改善的。比如重传丢包判断不行,也修改改小rto时长加快兜底重传。内存不足进入压力状态,可以通过调大tcp_mem缓解等等。但这些并不是问题发生了原因,难以保障之后运营质量,同样也只需要问几个问题。

“为啥没有办法处理window_scaling选项?”——可能内核比较老旧有bug

“为啥这个bug只在我们这触发了?”——无法解释

同样问题查到这里,根因也只查到一半。源站或者我们服务器端关闭window_scaling选项就能解决,但根因并未找到,那怎么办呢?这有点类似高中解算术题“题目解到一半,进行不下去怎么办?”。优秀的学生知道回去在看一遍题目,看下是不是漏了啥条件。而这里我们回到抓包来看,再多看几次pcap包,是否有啥漏掉的点。

还真看出两个不一样的点:第一,源站居然不支持sack选项。第二,第三次握手后就没有携带timestamp选项。有几年调优经验的工程师,往往能立刻想到是syn_cookie机制有关,多多少少查过ddos攻击的问题。syn_cookie机制下,会将window_scaling选项加密到时间戳选项中,第三次握手时从时间戳字段中解密对应的window_scaling。而至于不支持sack的原因,更早的版本只有将window_scaling加密到时间戳中,sack选项是之后的版本才加入时间戳选项中。

本质原因有进一步进展,第三次握手的timestamp没有正常工作导致的。服务端使用的是定制内核,第二次握手处理源站syn_ack调用了timestamp选项处理函数为tcp_parse_options(),该函数的对TCP_TIMESTAMP选项的进行了修改,增加了tcp_wan_timestamps选项,当设置为0是,内网IP才能正常解析timestamp。机器上一看配置,这个参数还真设置为0。

所以结论变为“源站半连接队列配置过小”+“内核新增特性不兼容”导致的。半连接队列过小,导致了syn_cookie机制容易被触发,syn_cookie触发后某些功能依赖timestamp选项,而定制内核的timestamp功能不完善,会造成质量受损。联系了内核开发团队,该功能主要解决外网某些客户端tcp_timestamp过于异常,造成rtt被错误更新。所以外网ip关闭时间戳选项,但为何第一次不直接关闭timestamp?估计就是bug改漏了...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值