【发布时间】: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,而不是自己编写。该库支持各种日志记录,例如文件、数据库、电子邮件等。