【问题标题】:Can high load cause PHP to not be able to write to a textfile?高负载会导致 PHP 无法写入文本文件吗?
【发布时间】:2019-09-12 06:46:59
【问题描述】:

我有一个 PHP 脚本,该脚本处于高负载状态,每秒调用多次(来自另一台计算机)。它在 IIS 服务器上的 PHP 5.5.14 上运行。使用

记录对脚本的每个请求和响应
file_put_contents('log_2019-09-12.txt', $msg, FILE_APPEND);

每个请求和响应也会记录在客户端计算机上,我偶尔会看到类似这样的 PHP 错误:

PHP ERROR 2: file_put_contents(C:\\WWW\\project-x\\logs\\log_2019-09-11.txt): failed to open stream: Permission denied

这些似乎大约每 140 分钟发生一次,通常有 8 个连续发生,然后再工作 140 分钟,每秒处理多个请求并成功记录到日志文件。

难道 PHP 通常会写入内存中的文件,然后实际上每 140 分钟将内容写入磁盘,这就是导致此错误的原因吗?如果是这样,我该如何规避它?

【问题讨论】:

  • 当第二个电话进来并尝试编辑同一个文件时,是否仍在写入同一个文件?
  • 这很可能是一个竞争条件问题。更简单的方法是将日志存储在 DB 上并让它处理,否则我认为您需要构建某种排队算法才能对它进行排序。
  • @NicoShultz 这是一种可能性,但我认为 PHP 足够聪明来处理这些类型的冲突?特别是考虑到有数百万个网站运行 PHP 并可能使用 file_put_contents,如果 Stackoverflow 不能处理对文件的并发访问,现在应该会被这些类型的错误所淹没......?
  • @MagnusW 是的,我也猜到了,但如果不是这样的话,我不会那么惊讶:) 也许你可以检查他试图写入文件的内容,看看是否有内容有什么奇怪的吗?只需添加一个 try catch 并转储 $msg
  • 尝试在写入时添加LOCK_EX 参数:file_put_contents($file, $text, FILE_APPEND|LOCK_EX)。从手册中:“LOCK_EX 标志以防止其他人同时写入文件”,我会使用一个日志库,如Monolog,而不是自己编写。该库支持各种日志记录,例如文件、数据库、电子邮件等。

标签: php iis logging php-5.5


【解决方案1】:

由马格努斯·埃里克森 (Magnus Eriksson) 在 cmets 中回答

尝试在写入时添加LOCK_EX 参数:file_put_contents($file, $text, FILE_APPEND|LOCK_EX) 来自手册:the LOCK_EX flag to prevent anyone else writing to the file at the same time

【讨论】:

    【解决方案2】:

    你没有写这个的权限。 mkdir($路径,0755,真) 写的时候检查你是否有权限。

    【讨论】:

    • 如果他没有权限,它总是会失败
    • 权限不是问题,因为它在其他 99.99% 的时间内成功写入同一个文件。
    • 我想出了两个解决方案。第一个是在写的时候锁定文件,第二个是创建一个临时文件来更新主文件。
    • 这真的是评论,而不是答案。多一点代表,you will be able to post comments。我正在标记这篇文章以供删除。
    猜你喜欢
    • 2010-12-29
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多