Php Apache是否在提供锁文件之前读取它们?
我有一个移动应用程序,可以读取存储在Apache服务器上的JSON文件。如果通过GUI更改了某些内容,则会重新生成JSON文件的内容(使用PHP脚本)Php Apache是否在提供锁文件之前读取它们?,php,json,apache,locking,Php,Json,Apache,Locking,我有一个移动应用程序,可以读取存储在Apache服务器上的JSON文件。如果通过GUI更改了某些内容,则会重新生成JSON文件的内容(使用PHP脚本) 我担心在Apache服务中试图重写JSON文件可能会引起问题。 Apache在提供文件之前是否获得读取锁?如果没有,如果我尝试在提供服务的同时写入,会发生什么情况?否。在POSIX兼容的系统上,所有锁都是建议性的,因此,即使apache获得读锁,另一个进程也可以直接写入文件 您可以使用strace确定: [pid 7246] open("/va
我担心在Apache服务中试图重写JSON文件可能会引起问题。
Apache在提供文件之前是否获得读取锁?如果没有,如果我尝试在提供服务的同时写入,会发生什么情况?否。在POSIX兼容的系统上,所有锁都是建议性的,因此,即使apache获得读锁,另一个进程也可以直接写入文件 您可以使用
strace
确定:
[pid 7246] open("/var/www/file.json", O_RDONLY|O_CLOEXEC) = 11
[pid 7246] fcntl(11, F_GETFD) = 0x1 (flags FD_CLOEXEC)
[pid 7246] mmap(NULL, 20, PROT_READ, MAP_SHARED, 11, 0) = 0x7f53f93da000
[pid 7246] munmap(0x7f53f93da000, 20) = 0
[pid 7246] writev(10, [{"HTTP/1.1 200 OK\r\nDate: Thu, 26 J"}, ...) = 365
[pid 7246] close(11) = 0
因此,JSON文件可能只是部分写入。要避免此问题,请将JSON文件写入同一文件系统上的临时文件,并使用原子重命名覆盖该文件
这样,如果打开
成功,apache将继续为旧文件提供服务。如果重命名
在打开
之前完成,apache将获得新的完整文件
如果您担心一致性(在电源故障或其他情况下),您可能还希望在关闭JSON文件之前调用写入JSON文件的应用程序。对于*nix平台,您的想法是错误的。您需要的是将原子文件写入脚本中的JSON文件。您可以通过将文件写入目标目录中唯一的临时文件名,然后使用rename()
将此文件移到旧文件上来完成此操作。文件移动操作是原子的。异步进程将打开旧的JSON文件或新的JSON文件,但不是混合文件
有多种方法可以构造临时文件名。请参阅tempnam()
上的PHP文档用户注释。我的系统生成一个请求唯一ID,所以我只使用$\u SERVER[“unique\u ID”]
作为基础。你真的需要一个“物理”文件,还是只需要输出内容就可以伪造文件?如果我使用PHP并得到一个写锁,可以吗?@cdmckay不,写锁没有效果,因为apache没有读锁。我扩展了答案。简而言之:使用。出于好奇,为什么ApacheRead不锁定它们?性能?@cdmckay那么,为什么apache read要锁定它们呢?请记住,所有这些,特别是如果它们像flock那样产生了令人望而却步的性能成本。