首页 > 解决方案 > 通过 Curl API 下载 Curl 很慢

问题描述

我正在使用 CURL 库下载文件。我们将 https:// 与 TLS 1.2 一起使用。使用的卷曲版本是 7.48.0。我们正在观察一个奇怪的问题。对于 224 MB 的文件大小,Curl 下载在服务器和客户端之间运行非常缓慢。如果我们使用 curl 的命令行工具,它的速度非常快,但如果我们从应用程序端调用“curl_easy_perform”,情况就不是这样了。

另外,我们使用 --libcurl 选项来检查命令行和我们的代码之间的差异,但没有。我们使用与命令行工具相同的选项,但通过直接调用 curl_easy_perform 完成下载仍然很慢。

如果我们从其他服务器和同一个客户端进行下载,它工作正常。但是,只有在特定服务器上,我们才会遇到下载时间问题。进一步调试,我们发现 netstat 输出显示 tcp socket 的接收队列非常高。但是,不清楚为什么这只是通过我们的程序而不是通过命令行成为问题,即使设置了相同的选项。

标签: curllibcurl

解决方案


事实证明,这个问题是因为写回调,这在这个服务器上花费了时间。在应用层的写回调中,我们已经完成了malloc、memcpy和free复制接收到的新数据。这适用于除一台以外的所有服务器。与该服务器连接的不同之处在于,Curl 在 Write 回调中给出了 16378 后跟 6 个字节的数据,而对于其他运行良好的服务器,它总是给出 16384 个字节的数据。这与设备上默认为套接字缓冲区设置的 rmem_max 大小相同。不知道为什么对于特定的服务器(Wildfly),它分成 16378 个字节,后跟 6 个字节。这导致下载 224 MB 文件大小的连续 malloc、memcpy 和免费循环。结果,从套接字读取变得非常缓慢,从而导致下载缓慢。在 Curl 命令行工具中,write 回调的写入方式不同,其中打开文件并通过在接收到数据时定期调用 fwrite 将数据写入该文件,然后在接收到所有数据后调用 fclose。与 malloc、memcpy 和 free 操作相比,这是非常快的操作。因此 curl 命令行工具可以很好地下载相同的文件。我们更改了我们的 write 调用,以与 curl 命令行所做的相同方式对齐,它解决了这个问题。但是,对于这个特定的服务器,Curl 将数据划分为 16378 + 6 字节的原因尚不清楚,我将进一步调查。与 malloc、memcpy 和 free 操作相比,这是非常快的操作。因此 curl 命令行工具可以很好地下载相同的文件。我们更改了我们的 write 调用,以与 curl 命令行所做的相同方式对齐,它解决了这个问题。但是,对于这个特定的服务器,Curl 将数据划分为 16378 + 6 字节的原因尚不清楚,我将进一步调查。与 malloc、memcpy 和 free 操作相比,这是非常快的操作。因此 curl 命令行工具可以很好地下载相同的文件。我们更改了我们的 write 调用,以与 curl 命令行所做的相同方式对齐,它解决了这个问题。但是,对于这个特定的服务器,Curl 将数据划分为 16378 + 6 字节的原因尚不清楚,我将进一步调查。


推荐阅读