【问题标题】:cURL/PHP Request Executes 50% of the TimecURL/PHP 请求执行 50% 的时间
【发布时间】:2011-05-28 16:06:47
【问题描述】:

在搜索完所有内容后,我无法理解为什么在我的案例中,向启用 SSL 的远程主机发出的 cURL 请求只有 50% 左右的成功率。情况如下:我有一系列 cURL 请求,所有这些请求都发送到 HTTPS 远程主机,在我使用 PHP CLI 运行的单个 PHP 脚本中。有时,当我运行脚本时,请求会成功执行,但由于某种原因,大多数时候我运行它时会从 cURL 收到以下错误:

* About to connect() to www.virginia.edu port 443 (#0)
*   Trying 128.143.22.36... * connected
* Connected to www.virginia.edu (128.143.22.36) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* error:140943FC:SSL routines:SSL3_READ_BYTES:sslv3 alert bad record mac
* Closing connection #0

如果我再试几次,我会得到相同的结果,但在几次尝试后,请求将成功通过。之后再次运行脚本会导致错误,并且模式会继续。研究错误“alert bad record mac”并没有给我任何帮助,我犹豫将其归咎于 SSL 问题,因为脚本仍然偶尔运行。

我在 Ubuntu Server 10.04 上,安装了 php5 和 php5-curl,以及最新版本的 openssl。在 cURL 特定选项方面,CURLOPT_SSL_VERIFYPEER 设置为 false,CURLOPT_TIMEOUT 和 CURLOPT_CONNECTTIMEOUT 都设置为 4 秒。进一步说明这个问题的事实是,在我的 Mac OS X 开发机器上也发生了同样的情况 - 请求只经过约 50% 的时间。

【问题讨论】:

  • 您可能想在 Google 上搜索“错误 140943FC”
  • 相信我,我做到了。我什至检查以确保我在 prefork MPM 中而不是工作线程中运行 Apache,因为显然存在由工作线程版本引起的与此相关的错误(我已经在运行 prefork,所以它没有帮助)。
  • 坏记录MAC不是指网络接口的MAC地址。它指的是“消息验证码”的问题

标签: php ssl curl ubuntu-10.04


【解决方案1】:

远程主机可能不是真正的唯一主机。也许这是某种负载平衡解决方案,有几台服务器接收传入的请求。 是什么让我认为这可能是错误消息中的“mac错误”。这可能意味着远程主机 mac 地址在 SSL 协商仍在运行时已更改。这可以解释有时你没有任何问题。

但也许不是 :-) SSL 问题很难找到。

我不明白你对 prefork MPM 与 Worker MPM 的回答,如果你在 cli 模式下运行 PHP,你的 apache MPM 没有被使用,你甚至没有使用 apache。

【讨论】:

  • 好点,负载平衡的远程主机在我的情况下是有意义的。为了解决这个问题,我决定阻止,直到我能得到一个有效的、非错误的 curl 响应并从那里开始。我现在得到的最好的。
  • 我认为 MAC 与网络 MAC 地址没有任何关系。它代表消息身份验证代码:en.wikipedia.org/wiki/Message_authentication_code ... 这使我得出结论,“远程主机 MAC 地址”更改与此问题无关,反之亦然。
  • @Charles Oliver Nutter 不错,但这可能仍然是主机之间应该共享的东西(ssl 缓存?)的问题。
  • @regilero 那么建议的解决方案是什么?
  • 如果是共享缓存问题,那么解决方案是使用共享驱动器 (NFS?) 进行 SSL 缓存。但这取决于真正的问题。
【解决方案2】:

你可能需要这个选项:

CURLOPT_FORBID_REUSE

长传。设置为 1 以使下一次传输在完成后显式关闭连接。通常,libcurl 在完成一次传输后会保持所有连接处于活动状态,以防随后的传输可以重用它们。此选项应谨慎使用,并且仅在您了解其作用的情况下使用。设置为 0 以使 libcurl 保持连接打开以供以后重用(默认行为)。

【讨论】:

  • 感谢您的建议,但无济于事。我之前尝试过 CURLOPT_FRESH_CONNECT 但这没有用,并且 FORBID_REUSE 导致了相同的旧行为。
【解决方案3】:

你试过了吗? curl_setopt($handle, CURLOPT_SSLVERSION, 3);

【讨论】:

    猜你喜欢
    • 2015-03-23
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 2018-08-26
    • 2012-03-07
    • 2017-08-30
    • 1970-01-01
    • 2021-08-02
    相关资源
    最近更新 更多