使用PHP Curl库的持久/ keepalive HTTP?

Fra*_*mer 59 php curl http libcurl keep-alive

我正在使用一个简单的PHP库通过HTTP将文档添加到SOLR索引.

目前涉及3台服务器:

  1. 运行索引作业的PHP框
  2. 一个数据库框,其中包含要编制索引的数据
  3. solr盒子.

在80个文档/秒(100万个文档中),我注意到PHP和solr盒子上的网络接口上的异常高的中断率(2000 /秒;更重要的是,图表几乎相同 - 当中断时PHP盒子峰值的速率,它也在Solr盒子上激增),但在数据库盒子上却少得多(300 /秒).我想这只是因为我打开并重用了一个到数据库服务器的连接,但是每个Solr请求当前都是通过cURL打开一个新的HTTP连接,这要归功于Solr客户端库的编写方式.

所以,我的问题是:

  1. cURL可以打开一个keepalive会话吗?
  2. 重用连接需要什么? - 它是否像重用cURL句柄资源一样简单?
  3. 我是否需要设置任何特殊的cURL选项?(例如强制HTTP 1.1?)
  4. 有没有关于cURL keepalive连接的陷阱?这个脚本一次运行几个小时; 我可以使用单个连接,还是需要定期重新连接?

Pis*_*3.0 54

cURL PHP文档(curl_setopt)说:

CURLOPT_FORBID_REUSE - TRUE强制连接在处理完成后显式关闭,而不是合并重用.

所以:

  1. 是的,实际上它应该在默认情况下重新使用连接,只要您重新使用cURL句柄即可.
  2. 默认情况下,cURL自己处理持久连接; 如果您需要一些特殊的标题,请检查CURLOPT_HTTPHEADER
  3. 服务器可能会发送保持活动超时(使用默认的Apache安装,它是15秒或100个请求,以先到者为准) - 但是当发生这种情况时,cURL将只打开另一个连接.

  • 杰出的!我差一点就要发布我的第一个 stackoverflow 问题了。如果我们添加了请求标头“Connection: close”,则该解决方案适用于我们的中间件。 (2认同)

小智 21

Curl默认发送keep-alive头,但是:

  1. 使用curl_init()不带任何参数创建上下文.
  2. 将上下文存储在它将存活的范围内(不是本地var)
  3. 使用CURLOPT_URL选项将url传递给上下文
  4. 使用执行请求 curl_exec()
  5. 不要关闭连接 curl_close()

非常基本的例子:

function get($url) {
    global $context;
    curl_setopt($context, CURLOPT_URL, $url);
    return curl_exec($context);
}

$context = curl_init();
//multiple calls to get() here
curl_close($context);
Run Code Online (Sandbox Code Playgroud)


Ole*_*hay 14

  1. 在您正在访问的服务器上,必须启用keep-alive,并且最大保持活动请求应该是合理的.对于Apache,请参阅apache文档.

  2. 您必须重新使用相同的cURL上下文.

  3. 配置cURL上下文时,在标头中启用keep-alive with timeout:

    curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array(
        'Connection: Keep-Alive',
        'Keep-Alive: 300'
    ));
    
    Run Code Online (Sandbox Code Playgroud)

  • 弗兰克,我刚刚重新测试了我的代码,默认情况下它看起来是开启的.虽然明确地设置它可能不会伤害. (2认同)