PHP函数在运行时冻结整个网站
Posted
技术标签:
【中文标题】PHP函数在运行时冻结整个网站【英文标题】:PHP function freezing entire website while it runs 【发布时间】:2018-11-17 10:02:09 【问题描述】:我在 Laravel 中有一个控制器方法,它在运行时冻结整个站点 - 例如,在运行时尝试加载任何页面只会挂起,直到函数完成执行。
所以我尝试将其分解以查看问题所在,我怀疑是数据库锁定等,但最后我尝试了一些新的东西并得出了一个意想不到的结论 - 函数中发生的事情无关紧要!
我将方法的全部内容替换为sleep(30);
,30 秒后,整个站点不可用。
所以我猜想一些资源正在跨应用程序共享,所有其他页面都必须等待该方法执行后才能运行。
我的问题是,为什么会发生这种情况,我如何具体找出有问题的资源是什么?
【问题讨论】:
信息不足。分享该功能的代码,分享您的日志等 在网站6年后,你应该知道不要在没有相关代码的情况下发帖。 它可能会阻塞会话。你可以使用session_write_close()
来解决这个问题。
也许将您的站点剥离为两个非常基本的 php 页面,一个带有 echo、sleep 和 echo,一个带有 echo。它仍然阻塞吗?
I replaced the entire contents of the method with sleep(30);
这个实验毫无价值——它只是表明sleep()
正在按照规范工作。您需要调试真实代码而不是睡眠功能。将一堆 echo microtime(true);
语句放入有问题的代码中,看看代码的哪些部分产生了最高的延迟。
【参考方案1】:
如果这只发生在同一个会话中,很可能是会话锁定。
每当您启动 session_start() 时(或者当 PHP 的 session.auto_start 设置为 true 时,它会在每个 PHP 脚本中自动执行此操作),操作系统将锁定会话文件。大多数实现都使用flock,它也用于防止重叠的cronjobs或Linux上的其他文件锁。
…
该锁定一直保留在文件上,直到脚本结束或有意删除锁定(更多内容见下文)。这既是一个读锁又是一个写锁:每次尝试读取会话都必须等到锁被释放。
锁本身不是问题。这是一种保护措施,可防止从多个位置写入会话文件,可能会损坏数据或删除以前的数据。
当第二个并发 PHP 脚本尝试访问同一个 PHP 会话时,就会出现问题。
更多信息在这里:https://ma.ttias.be/php-session-locking-prevent-sessions-blocking-in-requests/
【讨论】:
不只是针对同一个会话,所以这个答案没有抓住重点。以上是关于PHP函数在运行时冻结整个网站的主要内容,如果未能解决你的问题,请参考以下文章
Python & Tkinter -> 关于调用冻结程序的长时间运行函数