2012-01-26 4 views
8

私は、Apacheサーバーに保存されているJSONファイルを読み込むモバイルアプリを持っています。 GUIを介して何かが変更された場合、そのJSONファイルの内容は(PHPスクリプトを使用して)再生成されます。Apacheはサービスを提供する前にファイルを読み取りますか?

JSONファイルをApacheで処理している間に上書きしようとすると、問題が発生する可能性があります。

Apacheはファイルを提供する前に読み取りロックを取得していますか?もしそうでなければ、それが奉仕されているのと同時に書こうとするとどうなるでしょうか?

+0

本当に '物理的な'ファイルが必要ですか、コンテンツを出力するだけでファイルを偽造できますか? – PeeHaa

答えて

9

いいえPOSIX互換システムでは、すべてのロックはとにかく助言されるので、たとえApacheが読み取りロックを取得しても、他のプロセスはファイルを書き込むことができます。したがって

[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ファイルが部分的にしか書かれていることを発生します

あなたはstraceと判断することができます。この問題を回避するには、JSONファイルを同じファイルシステム上のテンポラリファイルに書き込んで、アブゾートrenameを使用してファイルを上書きします。

こうすれば、openが成功した場合、apacheは古いファイルを引き続き提供します。 openの前にrenameが終了すると、Apacheは完成した新しいファイルを取得します。

一貫性(電源障害などの場合)が心配な場合は、閉じる前にJSONファイルを書き込むアプリケーションでfsyncに電話することもできます。

+0

PHPのhttp://php.net/manual/en/function.flock.phpを使用して書き込みロックを取得しても問題ありませんか? – cdmckay

+0

@cdmckayいいえ、書き込みロックは効果がありません。なぜなら、apacheは読み取りロックを取得しないからです。私は答えを広げた。要するに:['rename'](http://php.net/rename)を使用してください。 – phihag

+0

好奇心から、なぜApacheはそれらを読み込みロックしないのですか?パフォーマンス? – cdmckay

1

あなたは* nixプラットフォームの間違ったパラダイムを考えています。あなたが望むのは、スクリプト内のJSONファイルへのアトミックなファイル書き込みです。これを行うには、ターゲットディレクトリの一意の一時ファイル名にファイルを書き込み、次にrename()を使用してこのファイルを古いディレクトリに移動します。ファイルの移動操作はアトミックです。非同期プロセスは古いJSONファイルまたは新しいものを開きますが、ハイブリッドは開きません。

一時ファイル名を構成する方法はさまざまです。 tempnam()に関するPHPドキュメントのユーザーコメントを参照してください。私のシステムはリクエスト固有のIDを生成するので、ちょうど$_SERVER["UNIQUE_ID"]をベースとして使用します。

関連する問題