我想使用libcurl实现HTTP通知系统。基本上,我有一个线程工作者池和一个通知队列。将通知放入队列后,池中的空闲工作程序将其接收并将其发送给接收方(主机,ip和URL路径是通知的参数)。
我的第一个实现基于curl easy interface。因此,基本上每个工作人员都运行以下代码(简化版):
static void* workerFunc(...) {
CURL* curlHandler = curl_easy_init();
for (;;) {
// Takes a notification from the queue
// Use curlHandler to send it, e.g:
//
// curl_easy_setopt(curlHandler , CURLOPT_URL, <notification URL>);
// curl_easy_setopt(curlHandler , CURLOPT_POSTFIELDS, <notification payload>);
// etc.
//
// CURLcode res = curl_easy_perform(curlHandler);
}
}
到目前为止,一切都很好。该代码有效。
但是,它有一个问题:curlHandler
对象是每个工作线程本地的,因此我们不利用libcurl在后台(默认为libcurl keeps a cache of 5 connections per handler)进行的连接重用。当系统的负载(即队列中已发布的通知)很高时,这可能是一个严重的问题,因为我们可能会以打开过多的并行连接来结束向同一目的地的访问,而不是重新使用它们。
在最坏的情况下,让我们想象一下,例如对于400个工作人员池,所有通知都具有相同的目的地(不用说example.com:9999
)。在高负载情况下(所有工作人员并行发送通知),我们最终可以同时与example.com:9000
建立400 x 5 = 2000个连接!
我解决这个问题的第一个想法是使curlHandler
对象成为全局对象。这样,我们可以为所有工作人员利用相同的libcurl连接池。但是,除非我实现基于互斥/信号量的保护机制,否则我想由于多线程(即两个线程在curl_easy_setopt(curlHandler , CURLOPT_URL, <notification URL>)
上发生冲突)将无法正常工作。
在自己的代码中处理mutext / sempahores总是很困难,所以我想知道是否有其他解决方案(可能在libcurl级别itslef上实现)更容易。我查看了licurl文档,该文档非常适合作为单个函数的参考,并且数据结构,但我还没有找到针对这种情况的具体说明(也许在这种情况下无法使用curl easy接口?)
请了解其他面临相同问题的人的经验以及可以采用的解决方案。
谢谢!