版权声明:本文由余子军原创文章,转载请注明出处: 
文章原文链接:https://www.qcloud.com/community/article/104

来源:腾云阁 https://www.qcloud.com/community

发现访问公司某些业务时,速度非常不稳定,并且整体慢于竞争对手。分析认为SESU10母盘上内核TCP拥塞控制算法和Windows的Ack频率控制的策略存在不兼容情况。

目前至少确认 2.6.16内核版本存在此问题;打TCP优化补丁或者更换Tlinux以后可以解决问题。

问题现象:

在体验网环境下测试:大文件下载的情况下,百度的下载速度平均在600KBPS,我们的下载速度平均低于100Kbps;互娱Webgame情况下,TNT业务下载速度大约是DDT的25%。

这里是一个典型的下载速度曲线:

我们的服务器的曲线:(纵轴单位:包/s)

百度的服务器下载的曲线:

重现该问题的测试环境:

网络: 公司体验网,普通联通4M ADSL

服务器:Linux64位服务器, 深圳机房。

服务器程序: Apache,nws(自研webserver)

客户端: Windows XP, Windows7,任意浏览器或者旋风(单线程下载)

测试工具:wireshark, httpwatch

测试连接:分别是自建CDN、百度下载、深圳DC+Apache

问题分析:

通过客户端抓包分析发现速度很慢的段有两个问题:

  1. 服务器端总是等到前面的数据包确认以后才发送第二个包

  2. Windows总是等到200ms左右才发送ACK确认。

对于Windows端的行为, 为了防止ACK过多导致网络压力,Ms TCP协议栈在每收到一个数据包时,启动一个200ms定时器,直到收到其他数据包或者定时器过期时才发送ACK包。

通过设置注册表选项 TcpAckFrequency 参数为1关闭 Ack delay以后,实验发现下载速度恢复正常,无法重现下载速度慢的问题。

To configure the max outstanding ACKs in Windows XP/2003/Vista/2008:

[HKEYLOCALMACHINE \SYSTEM \CurrentControlSet \Services \Tcpip \Parameters \Interfaces \{Adapter-id}]

TcpAckFrequency = 1 (Default=2, 1=Disables delayed ACK, 2-n = If n outstanding ACKs before timed interval, sent ACK)

因为无法强制用户通过修改注册表避免问题,并且竞争对手也没有看到类似问题,因此只能从linux端解决。

Linux这一端,首先怀疑和nagle算法有关系,在nws服务器上设置TCP_NODELAY以后仍然可以重现,可以排除Nagle算法的影响。 (实际上nws每次发送大数据包或者直接使用sendfile,不太会收到nagle算法影响) 其次Apache,nws都可以重现这个问题,比较怀疑操作系统本身有缺陷。

因为每次linux仅发送一个数据包,因此怀疑拥塞窗口的问题,推测问题如下:

初始情况下,客户端回复一个ACK时,拥塞窗口增大,每次发送多个数据包,因此刚开始可以有较快的传输速度;因为网络延时抖动或丢包导致服务器协议栈判定数据包超时,重置拥塞窗口为1,每次仅发送一个数据包,收到客户端200ms回包,时仍然认为超时,同时调整RTT;直到RTT增大到200ms不算超时为止,拥塞窗口得以扩大,可以发送多个数据包,传输速度增快,如此循环。

通过测试增大初始拥塞窗口为10 (更换内核加载架平新技术组的TCP优化模块实现),下载速度恢复正常。

附旋风测试选项:

参考:
http://smallvoid.com/article/winnt-nagle-algorithm.html
http://support.microsoft.com/kb/214397/en-us

Linux 2.6.16 TCP连接速度异常的问题分析的更多相关文章

  1. .netcore项目部署到linux的docker里后,速度异常的慢

    .netcore项目部署到linux的docker里后,速度异常的慢,部署在iis下速度非常快. 特别是 接口里再调用其他接口,那速度绝对是蜗牛爬行的速度. 经过几个月的折腾,终于知道是什么问题了: ...

  2. Linux 内核协议栈之TCP连接关闭

    Close行为: 当应用程序在调用close()函数关闭TCP连接时,Linux内核的默认行为是将套接口发送队列里的原有数据(比如之前残留的数据)以及新加入 的数据(比如函数close()产生的FIN ...

  3. TCP连接可能出现的异常总结

    1.java.net.BindException:Address already in use:bind 服务端出错,两次对同一个端口进行启动(会在服务端发生报错,抛出异常,不考虑) 2.java.n ...

  4. 我为 Netty 贡献源码 | 且看 Netty 如何应对 TCP 连接的正常关闭,异常关闭,半关闭场景

    欢迎关注公众号:bin的技术小屋,本文图片加载不出来的话可查看公众号原文 本系列Netty源码解析文章基于 4.1.56.Final版本 写在前面..... 本文是笔者肉眼盯 Bug 系列的第三弹,前 ...

  5. tcpkill清除异常tcp连接

    tcpkill清除异常tcp连接 在linux系统中,遇到TCP链接迟迟不能释放的情况,类似FIN_WAIT1.FIN_WAIT2的状态,释放时间不确定,而且对应的程序已经关闭,相应的端口也不再监听, ...

  6. 【NodeJs】Ctrl+C在Linux平台和Windows平台下的TCP连接中的不同表现

    Linux平台:CentOS release 6.5 (Final) Windows平台:Windows 7 旗舰版 服务器端代码如下: var net = require('net'); var s ...

  7. Linux 建立 TCP 连接的超时时间分析(解惑)

    Linux 系统默认的建立 TCP 连接的超时时间为 127 秒,对于许多客户端来说,这个时间都太长了, 特别是当这个客户端实际上是一个服务的时候,更希望能够尽早失败,以便能够选择其它的可用服务重新尝 ...

  8. 修改Linux内核参数,减少TCP连接中的TIME-WAIT

    一台服务器CPU和内存资源额定有限的情况下,如何提高服务器的性能是作为系统运维的重要工作.要提高Linux系统下的负载能力,当网站发展起来之后,web连接数过多的问题就会日益明显.在节省成本的情况下, ...

  9. 配置开发支持高并发TCP连接的Linux应用程序全攻略

    http://blog.chinaunix.net/uid-20733992-id-3447120.html http://blog.chinaunix.net/space.php?uid=16480 ...

随机推荐

  1. Apache HttpComponents 获取Cookie

    package org.apache.http.examples.client; import java.util.List; import org.apache.http.HttpEntity; i ...

  2. LINQ操作符一:Select

    一.什么是LINQ?它可以用来做什么 语言集成查询(Language Integrated Query,LINQ)是一系列标准查询操作符的集合,这些操作符几乎对每一种数据源的导航.过滤和执行操作都提供 ...

  3. R语言--saprkR基本使用

    1.在sparkR的shell中交互式使用 sparkR --masterspark://10.130.2.20:7077 sparkR --masterlocal[6] #sparkR --mast ...

  4. 关于Unity的入门游戏飞机大战的开发(下)

    开发思路: 1: 修改测试模式,去掉开始按钮方便开发,加入敌机的资源2: 创建敌机 添加刚体,碰撞器组件,添加帧动画播放组件;3: 创建敌机出现的队形;4: 根据队形随机 生成我们的敌机,调整敌机的速 ...

  5. Java 二维码--转载

    周末试用下Android手机的二维码扫描软件,扫描了下火车票.名片等等,觉得非常不错很有意思的.当然Java也可以实现这些,现在就分享下如何简单用Java实现二维码中QRCode的编码和解码(可以手机 ...

  6. getaddrinfo ENOTFOUND https://api.weixin.qq.com https://api.weixin.qq.com:443

    原因:这是由于你当前的主机不能够连接到你填写的url. 解决方法: 先ping api.weixin.qq.com ping不通的话,就是外网访问的问题. 开通外网访问就可以了.

  7. 创建以API为中心的Web应用(转)

    英文原文:Creating an API-Centric Web Application 引言 API——API是Application Programming Interface(应用编程接口)的简 ...

  8. 转载:QTableView中嵌入可视化组件

    出处:http://qimo601.iteye.com/blog/1538364 QTableView中嵌入可视化组件方法有四种: 第一种不能之前显示,必须双击/选中后才能显示,不适用. 第二种比较简 ...

  9. LoadRunner 调用dll方法

    本文主要介绍简单DLL的编写方法及在LoadRunner中局部调用与全局调用DLL方法. 1.动态链接库的编写 在Visual C++6.0开发环境下,打开FileNewProject选项,可以选择W ...

  10. Unity3D手机平台分辨率自动匹配教程

    1. 下载NGUI 2. 导入NGUI package到Unity. 这时候菜单上会出现NGUI的菜单栏: 3. 将默认的Main Camera删掉,通过菜单栏NGUI->Create新建一个2 ...