Does Apache read-lock files before serving them?

巧了我就是萌 提交于 2019-12-01 15:39:00

问题


I have an mobile app that reads a JSON file that is stored on an Apache server. The contents of that JSON file are regenerated (using a PHP script) if something is changed via a GUI.

I am worried that trying to overwrite the JSON file in the middle of it being served by Apache might cause problems.

Does Apache obtain a read lock before serving files? If not, what will happen if I try to write it at the same time it is being served?


回答1:


No. On POSIX-compatible systems, all locks are advisory anyways, so even if apache would get a read lock, the other process could just write the file.

You can determine that with 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

Therefore, it can happen that your JSON file is only partially written. To avoid this problem, write your JSON file to a temporary file on the same filesystem, and use the atomic rename to overwrite the file.

That way, if the open has succeeded, apache will continue serving the old file. If the rename finishes before the open, apache will get the new, completed file.

If you worry about consistency (in the case of a power failure or so), you may also want to call fsync in the application that writes the JSON file before closing it.




回答2:


You're thinking in the wrong paradigm for *nix platforms. What you want are atomic file writes to the JSON file in your script. You do this by writing the file to a unique temporary filename in the target directory then using rename() to move this file over the old one. The file move operation is atomic. Asynchronous processes will either open the old JSON file or the new one but not a hybrid.

There are various ways to construct a temporary filename. See the PHP documentation user comments on tempnam(). My system generates a request unique ID, so I just use $_SERVER["UNIQUE_ID"] as the base.



来源:https://stackoverflow.com/questions/9021849/does-apache-read-lock-files-before-serving-them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!