Flock,你知多少?
PHP 中的 flock 函数可以让你的站点挂了,你信吗?不可能,不就是一个锁文件嘛。
我们所使用的是 Discuz! X3.2 版本,其中这个helper_log::writelog 函数中使用了 @flock($fp, 2); 此时如果你的日志目录(data/log/)使用了NFS(网络文件系统),这将在某些情况下是有问题的。
1. 先来看看 PHP 手册中的提示:
2. 再看看这个代码的执行:
<?php // $logfile = '/data/bbs3.2/data/log/201501_cplog.php'; // error // $logfile = '/tmp/test.log'; // ok // $logfile = '/home/zongym/201501_cplog.php'; // ok // $logfile = '/data/bbs3.2/data/log/201501_errorlog.php'; // ok $logfile = '/data/bbs3.2/data/log/201501_ssoapilog.php'; // error if($fp = @fopen($logfile, 'a')) { echo $logfile . "\n"; @flock($fp, 2); fclose($fp); } ?>
有两个标注为 error 的文件在执行时,脚本无法结束,其他均正常(与文件大小没有直接关系)。执行结果如图所示
对于站点来说,我们是使用的 nginx + php-fpm 方式,直接导致了php-fpm 进程达到上线,mysql 连接达到上线,最后服务彻底垮掉。
我们的解决方式是,把 writelog 中的 flock 一行注释掉,因为写日式不是非常核心的功能,如果一旦有错,也可以接受。不过还可以使用 memcache ,redis 等来进行独占锁实现。