Sichert Apache Dateien vor dem Versenden?

8

Ich habe eine mobile App, die eine JSON-Datei liest, die auf einem Apache-Server gespeichert ist. Der Inhalt dieser JSON-Datei wird neu generiert (mit einem PHP-Skript), wenn etwas über eine GUI geändert wird.

Ich bin besorgt, dass der Versuch, die JSON-Datei zu überschreiben, während sie von Apache bedient wird, Probleme verursachen könnte.

Erhält Apache vor dem Versenden von Dateien eine Lesesperre? Wenn nicht, was passiert, wenn ich versuche, es gleichzeitig zu schreiben?

    
cdmckay 26.01.2012, 16:48
quelle

2 Antworten

9

Nein. Auf POSIX-kompatiblen Systemen sind alle Sperren sowieso beratend. Selbst wenn Apache eine Lesesperre erhalten würde, könnte der andere Prozess nur die Datei schreiben.

Das kannst du mit strace :

bestimmen %Vor%

Daher kann es passieren, dass Ihre JSON-Datei nur teilweise geschrieben wird. Um dieses Problem zu vermeiden, schreiben Sie Ihre JSON-Datei in eine temporäre Datei im selben Dateisystem und verwenden Sie die atomare rename , um die Datei zu überschreiben.

Wenn die open erfolgreich war, wird apache auf diese Weise weiterhin die alte Datei bereitstellen. Wenn der rename vor dem open endet, erhält Apache die neue, vervollständigte Datei.

Wenn Sie sich Sorgen um Konsistenz machen (im Falle eines Stromausfalls oder so), können Sie auch % co_de aufrufen % in der Anwendung, die die JSON-Datei vor dem Schließen schreibt.

    
phihag 26.01.2012, 16:52
quelle
1

Sie denken im falschen Paradigma für * nix-Plattformen. Was Sie wollen, sind atomare Datei schreibt in die JSON-Datei in Ihrem Skript. Dazu schreiben Sie die Datei in einen eindeutigen temporären Dateinamen im Zielverzeichnis und verwenden dann rename() , um diese Datei über die alte Datei zu verschieben. Die Dateiverschiebeoperation ist atomar. Asynchrone Prozesse öffnen entweder die alte JSON-Datei oder die neue, aber keine Hybriddatei.

Es gibt verschiedene Möglichkeiten, einen temporären Dateinamen zu erstellen. Lesen Sie die Benutzerkommentare zur PHP-Dokumentation zu tempnam() . Mein System generiert eine eindeutige ID für die Anfrage, daher verwende ich einfach $_SERVER["UNIQUE_ID"] als Basis.

    
TerryE 26.01.2012 17:37
quelle

Tags und Links