我有一台在 Amazon EC2 实例上运行的 Windows Server 2012 R2,该实例装有 IIS 8.5。它托管一个 Web 应用程序和一个自定义 WebDAV 服务器,该服务器与 Web 应用程序的同一数据库进行交互。
我通过 Web 应用程序和自定义 WebDAV 服务器进行了一些文件上传速度测试。我注意到,使用 Microsoft 内置的微型重定向器通过 WebDAV 上传文件的速度非常慢 - 大约 300 kB/s。使用 Chrome 通过网站上传的速度与预期一致,为 10+ MB/s。
我在另一台服务器上运行了完全相同的 Web 应用程序和 WebDAV 服务器代码,该服务器运行 Windows Server 2008 和 IIS 7.5,并且 Web 应用程序和 WebDAV 服务器上的上传速度均为 10+ MB/s。因此,我很确定我的代码中没有任何东西导致上传速度缓慢。我花了几天时间研究这个问题,但还是无法将我的上传速度提高到 WebDAV 服务器应有的水平。
另一个有趣的现象是:我尝试使用 Internet Explorer 上传到 Web 应用程序,上传速度很慢 - 大约 300 kb/s,就像使用 mini-redirector 连接到 WebDAV 服务器时一样。我也测试了 Firefox,它和 Chrome 一样,速度为 10+ MB/s。
我打开 Fiddler 检查请求/响应,当 Fiddler 打开时,问题没有出现,上传速度为 10+ MB/s,所以我无法从 Fiddler 获得任何有用的信息。
我使用 Wireshark 检查 TCP 数据包并比较了运行速度快的 Windows Server 2008 与运行速度慢的 Windows Server 2012 之间的差异。
TCP 数据包的顺序和大小相同,两个数据包和一个 ACK,两个数据包和一个 ACK 等。数据包大小均为 4k 左右。唯一的区别是发送数据包的速率,在 Windows Server 2008 上,发送速率要快几个数量级。
我已在几台不同的客户端计算机上测试了上传速度 - Linux、Windows 7 和 Windows 8。我只看到此问题出现在 Windows 7 上,尽管这可能是巧合。它出现在大约 75% 的 Windows 7 计算机上,但并非所有 Windows 7 计算机上。
所有这些都让我相信这个问题一定是客户端/服务器端配置的组合,因为我无法将问题归结为发生在特定服务器上或特定客户端上。事实上,我已经设置了另一个 Windows Server 2008,与当前服务器相同,上传速度很快,但在新服务器上,上传速度仍然很慢。所以也许差异在于 NIC,或者可能是特定的修补程序和补丁、驱动程序等。
为了提高 Windows Server 2012 R2 的上传速度,我尝试了以下方法:
• 增加了SocketSendBuffer
客户端计算机上注册表中的 Winsock 长度
• 在服务器上禁用 Nagle 算法
• 禁用服务器上的 TCP Chimney Offload
• 启用/禁用我在网上各种文章中读到的大约 50 个其他 TCP 相关选项。
• 尝试从多个网络位置连接客户端(如果客户端上传速度很慢,则无论连接到哪里,上传速度都很慢)。
• 尝试使用 HTTP 代替 HTTPS,问题仍然存在,因此似乎与 SSL 或 TLS 无关。
• 确保自动检测代理和自动配置脚本在 IE 中未选中
• 确保keep-alive
在客户端请求标头中启用
有人知道是什么原因导致我的上传速度很慢吗?
再次重申,使用 Chrome 或 Firefox 通过 Web 应用程序上传时不会出现此问题,但使用 IE 时会出现此问题。在某些客户端计算机上使用 mini-redirector 时总会出现此问题,但在其他客户端计算机上从未出现过。
答案1
我可以通过在客户端计算机的 Windows 注册表中 更改Default Send Window
Winsock 驱动程序 - - 来解决该问题。afd.sys
导航到以下注册表项并添加一个新的 DWORD,其名称DefaultSendWindow
和 va 值(十进制)为 1920000
。
HKLM\System\CurrentControlSet\Services\AFD\Parameters
笔记:
该值应至少按照以下公式设置为与您宣传的上传速度一样高:
(Upload Speed Kbps / 8 ) * 1024 = DefaultSendWindow
例子:
广告上传速度:15 Mbps = 15,000 Kbps
(15000/8)*1024=1920000
此值通常在第三方软件的代码中被覆盖,但是 Microsoft 产品似乎不会覆盖它,可能是因为他们认为自己使用的默认值afd.sys
就足够了。这就是为什么我在使用 Chrome、Firefox、Filezilla 等时没有看到问题的原因......因为它们自己覆盖了这个值。似乎不同的文件版本使用afd.sys
不同的默认发送窗口值,这就是为什么这个错误没有出现在所有客户端机器上的原因。