使用PHP Curl库持久化/保留HTTP?

使用PHP Curl库持久化/保留HTTP?,php,http,curl,libcurl,keep-alive,Php,Http,Curl,Libcurl,Keep Alive,我使用一个简单的PHP库,通过HTTP将文档添加到SOLR索引中 目前涉及3台服务器: 运行索引作业的PHP框 保存要编制索引的数据的数据库框 solr盒子 在80个文档/秒(100万个文档中)的速度下,我注意到PHP和solr框上的网络接口的中断率异常高(2000/秒;而且,图形几乎相同——当PHP框上的中断率达到峰值时,solr框上的中断率也会达到峰值),但数据库框上的中断率要低得多(300/秒)。我想这仅仅是因为我打开并重用了一个到数据库服务器的连接,但是由于Solr客户端库的编写方式,每

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

目前涉及3台服务器:

  • 运行索引作业的PHP框
  • 保存要编制索引的数据的数据库框
  • solr盒子
  • 在80个文档/秒(100万个文档中)的速度下,我注意到PHP和solr框上的网络接口的中断率异常高(2000/秒;而且,图形几乎相同——当PHP框上的中断率达到峰值时,solr框上的中断率也会达到峰值),但数据库框上的中断率要低得多(300/秒)。我想这仅仅是因为我打开并重用了一个到数据库服务器的连接,但是由于Solr客户端库的编写方式,每个Solr请求当前都通过cURL打开了一个新的HTTP连接

    所以,我的问题是:

  • 可以使cURL打开一个keepalive会话吗
  • 重用连接需要什么条件?--它是否像重用cURL句柄资源那样简单
  • 我需要设置任何特殊的卷曲选项吗?(例如,强制HTTP 1.1?)
  • cURL-keepalive连接是否存在任何问题?此脚本一次运行数小时;我可以使用单个连接,还是需要定期重新连接

  • 如果您不关心来自请求的响应,那么可以异步执行这些操作,但您可能会导致SOLR索引过载。不过我怀疑,索尔真的很快

    cURL PHP文档()说:

    CURLOPT\u禁止重用
    -
    TRUE
    强制 要显式关闭的连接 完成处理后,以及 不能集中使用

    因此:

  • 是的,实际上默认情况下它应该重用连接,只要您重用cURL句柄
  • 默认情况下,cURL自己处理持久连接;如果您需要一些特殊的标题,请检查CURLOPT_HTTPHEADER
  • 服务器可能会发送一个keep-alive超时(对于默认的Apache安装,它是15秒或100个请求,以先到者为准),但是当发生这种情况时,cURL只会打开另一个连接
  • 在您正在访问的服务器上,必须启用保持活动,并且最大保持活动请求数应合理。对于Apache,请参阅

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

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

    curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array(
        'Connection: Keep-Alive',
        'Keep-Alive: 300'
    ));
    

  • 默认情况下,Curl发送keep-alive标头,但是:

  • 使用不带任何参数的
    curl\u init()
    创建上下文
  • 将上下文存储在它将继续存在的范围中(不是本地变量)
  • 使用
    CURLOPT_URL
    选项将URL传递到上下文
  • 使用
    curl\u exec()
  • 不要使用
    curl\u 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);
    

    我曾经在解析一个包含许多页面的整个站点时使用过它,这些页面需要身份验证并在整个过程中维护会话。使用inital handle资源,您可以继续执行命令以获取页面,并与客户端保持相同的会话和连接。使用命令行,这已经持续了大约20分钟(对于我们所有的数据需求,因此可能会持续更长时间),而无需重新连接。但我不确定这是否是你要问的,因此这是一个评论而不是回答:)另一个注意,通常需要根据你正在做的事情和连接到的服务器设置一些选项。所有这些都在这里得到了很好的记录:FAQ的这一部分是相关的,尽管不是很详细:我遇到了一个问题:通过一个curl句柄发出100000个请求后,我的脚本达到了512兆的内存使用量;在我开始重用连接之前,它从未超过60MB。我现在每1000个请求重新连接一次(这可能比必要的次数要多,但不够频繁,连接开销应该很小),还有:CURLOPT_MAXCONNECTS-允许的最大持久连接量。当达到限制时,使用CURLOPT_CLOSEPOLICY来确定要关闭的连接。这当然很有趣,但它根本没有解决连接重用问题。事实上,这只会让我的连接开销问题变得更糟。弗兰克,我刚刚重新测试了我的代码,默认情况下它看起来是打开的。不过,显式地设置它也无妨。@OlegBarshay您知道我们是否需要删除
    curl\u close($curlHandle)为了使连接保持活动状态?@zeflex是的,您必须将其移除,如果您调用
    curl\u close
    连接将关闭brilliant!我差一点就要发布我的第一个问题了。此解决方案适用于我们的中间件,前提是我们添加了请求头“Connection:close”。您还需要在第二次调用之前设置cookie,例如:
    curl\u setopt($context,CURLOPT\u cookie,'name=value')例如,我的请求是
    curl_setopt($context,CURLOPT_COOKIE,'PHPSESSID=bl392rgi8q664l7faat33hfta4')