使用Libcurl上传大数据时性能不佳

时间:2014-03-08 16:12:10

标签: c performance http curl tcp

我们有一个用C语言编写的应用程序,在Windows和Linux上运行,它使用libcurl的简单接口通过互联网上的HTTP API与Apache服务器进行交互。通常,API事务很短,带宽性能无关紧要,但最近我们不得不开始处理向API发送大量数据的事务。在我们的例子中,每个HTTP POST最多包含大约10MB,但可能只有几KB。我们将进行许多这样的交易,在程序执行期间从~100MB发送到100GB。

我们遇到的问题是我们的总带宽(发送的数据总量/(执行所有上传事务所花费的时间 - 服务器端处理时间))非常糟糕。如果我们将原始数据和FTP连接到托管Apache实例的同一个Web服务器,我们获得的带宽比当前设置高出约5倍。我们知道,以块的形式发送数据会在某种程度上影响性能,但是5倍的放缓似乎过度(可能不是,这就是我们要求的原因!)

我们正在寻找提高绩效的建议,或者在我们的限制条件下无法改进的原因。我们必须继续使用HTTP POST一次发送一个数据块。我们不依赖于libcurl,如果我们的情况有更快的替代方案,我们很乐意将它集成到我们的应用程序中。理想情况下,有一些方法可以配置libcurl以便在我们的非标准负载下更好地执行(我们已经阅读了有关TCP_CORK的信息,但是无法找到有关如何在libcurl中使用它的任何文档)。

粗略地说,我们的代码目前看起来像这样(为了简洁而删除了错误检查)

CURL *cur = curl_easy_init()))
struct curl_slist *headers = NULL
headers = curl_slist_append(headers, "Connection: Keep-Alive");
headers = curl_slist_append(headers, "Keep-Alive: 60");
headers = curl_slist_append(headers, "Content-Type: text/xml");
headers = curl_slist_append(headers, xff); // xff declared elsewhere

curl_easy_setopt(cur, CURLOPT_PROXY, proxyurl); // proxyurl declared elsewhere
// proxyauth declared elsewhere
curl_easy_setopt(cur, CURLOPT_PROXYUSERPWD, proxyauth);
curl_easy_setopt(cur, CURLOPT_URL, urlbuf); // urlbuf declared elsewhere
// user_agent declared elsewhere
curl_easy_setopt(cur, CURLOPT_USERAGENT, user_agent);
// callback makes a copy of a tiny (<100 byte) response which is processes later.
curl_easy_setopt(cur, CURLOPT_WRITEFUNCTION, callback);
curl_easy_setopt(cur, CURLOPT_WRITEDATA, ptr); // ptr declared elsewhere
// postBody is the up to ~10MB data buffer being sent
curl_easy_setopt(cur, CURLOPT_POSTFIELDS, postBody);
curl_easy_setopt(cur, CURLOPT_POSTFIELDSIZE, postBodySize); // postBody size
curl_easy_setopt(cur, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(cur, CURLOPT_BUFFERSIZE, CURL_MAX_WRITE_SIZE);
curl_easy_setopt(cur, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(cur, CURLOPT_SSL_VERIFYPEER, 0);
// connectTimeout declared elsewhere
curl_easy_setopt(cur, CURLOPT_CONNECTTIMEOUT, connectTimeout);
curl_easy_setopt(cur, CURLOPT_TIMEOUT, timeout); // timeout declared elsewhere
/* Turn on http keep-alive packets */
curl_easy_setopt(cur, CURLOPT_TCP_KEEPALIVE, 1);

curl_easy_perform(cur)

非常感谢任何和所有的想法/建议。

0 个答案:

没有答案