【问题标题】:How do I stop cURL from deadlocking my PHP session?如何阻止 cURL 使我的 PHP 会话死锁?
【发布时间】:2014-04-25 15:03:27
【问题描述】:

所以基本上,我使用 cURL 来调用我无法在 PHP 中本地实现的 API。但是,当我拨打电话时,它会使我的 PHP 会话死锁。我无法从浏览器中的另一个选项卡连接到我的网站。如果我删除会话 cookie,我可以正常连接。以前,当我在 cURL 中没有超时时,这会无限期地持续下去。

这只是 cURL 的 PHP 实现的工作方式,还是有解决方法?

【问题讨论】:

  • 这是一篇关于会话和 cURL 的好博文。 link
  • 是的,它就是这样工作的。 PHP 不支持线程,所以没有(简单的)方法可以避免这种阻塞。
  • 由于只有一个会话,它不能死锁。它可能会保留锁并且在超时或被杀死之前不会释放它,但这并不是一个死锁。

标签: php session curl


【解决方案1】:

here 所述,您可能想尝试在不打开会话的情况下执行 cURL 请求,例如通过在发送请求之前执行session_write_close() 并在您处理它之后执行session_start()

【讨论】:

  • 这是一个等待发生的意外——如果cURL后面的session_start()被另一个请求阻塞了怎么办?
  • @EugenRieck 只要您的脚本没有阻止会话过长的时间,我看不出有什么问题。如果您说发出 cURL 请求后的 session_start() 是一个问题,那么您必须考虑每隔一个 session_start() 调用同样有问题。
  • 如果我打开会话,从中读取所有值,然后立即关闭它,那么其他请求应该只被阻塞几毫秒,对吧?
【解决方案2】:

这与cURL无关:基本上每一个长时间运行的操作都容易出现同样的问题。

这是我们通常的处理方式:

  • 应该启动进程的请求(例如启动 cURL 命令)不应该这样做,而只是对其进行身份验证并为其创建一次性票证,将其存储在会话中并返回
  • 返回时,客户端现在应该请求运行 cURL,使用一次性票证,而不是会话。这使会话保持解锁状态。结果必须在中间存储。
  • 在完成长时间运行的过程后,客户端使用会话收集中间存储的结果。

【讨论】:

  • 所以客户端必须发送三个请求而不是一个?当然,它有效,但对我来说看起来不是很干净......
  • 重点是,长时间运行的进程与正常的控制流完全隔离。虽然这引入了(恕我直言可管理的)复杂性,但它通过分离“会话”和“长时间运行的请求”的不兼容概念来实现稳健性和模块化
  • @thejh 这很干净,因为客户端不会挂起等待长时间运行的操作。更复杂——是的。但更复杂并不意味着更不干净。我认为,试图猜测一个操作可能需要多长时间才能设置“正确的”超时值要麻烦得多。
  • @BrianWarshaw 我认为它不那么干净的原因是您正在以一种方式解决服务器端问题(您的软件无法处理属于一个会话的并行请求)涉及客户。在我看来,像这样的服务器端问题也应该在服务器上解决。
  • @thejh 虽然我明白了这一点,但我并不认为它 100% 有效:对同步和服务器使用同步客户端,对异步服务器使用异步客户端对我来说似乎很自然。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多