Das Ändern des Status einer Ressource ist eine Operation, die auf einem beliebigen System implementiert ist. Zu diesem Zeitpunkt ist unter Berücksichtigung der Integritätsgarantie eine Art Verriegelungsmechanismus erforderlich.
Unter Bezugnahme auf Zalando stellen wir hier die Konsistenz durch optimistisches Sperren beim Aktualisieren der RESTful-API sicher. Mal sehen, was die Idee in diesem Fall ist. Danach werden wir überlegen, was passieren würde, wenn wir tatsächlich optimistisches Sperren implementieren würden, und die Teile, die in Zalando nicht klar angegeben sind.
Zalandos Leitfaden zur RESTful-API bietet vier Möglichkeiten, um ein optimistisches Sperren zu erreichen.
Mal sehen, wie diese vier optimistische Sperren realisieren, wenn Listeninformationen über die API abgerufen und eine davon aktualisiert werden.
Der Aktualisierungsablauf und der optimistische Sperrablauf sind in der folgenden Abbildung dargestellt. Überprüfen Sie die Übereinstimmung / Nichtübereinstimmung zwischen dem Wert, der im Teil "Rückgabe mit Etag-Header" an die Clientseite zurückgegeben wurde, und dem Wert, der im Update "If-Match" mit dem "If-Match-Header" angegeben wurde, und sehen Sie sich den API-Server an. Entscheidet, ob aktualisiert werden soll.
Der Aktualisierungsablauf und der optimistische Sperrablauf sind in der folgenden Abbildung dargestellt. Verwenden Sie "Rückgabeliste", um alle Ressourcen abzurufen, die dem entsprechenden Endpunkt zugeordnet sind. Setzen Sie zu diesem Zeitpunkt den Wert jeder Ressource auf Startwert, erstellen Sie ein Etag mit einem Algorithmus und nehmen Sie es in die Antwort auf. Auf dem API-Server ist eine Aktualisierung möglich, abhängig davon, ob der Wert für "If-Match" in "Update" mit "If-Match-Header" und der neu berechnete etag-Wert der Ressource, die die Aktualisierung angefordert hat, identisch sind. Urteilen.
Der Aktualisierungsablauf und der optimistische Sperrablauf sind in der folgenden Abbildung dargestellt.
Der Client gibt eine Liste mit der Versionsnummer zurück und erfasst alle Ressourcen, die dem entsprechenden Endpunkt im Formular zugeordnet sind, einschließlich der Versionsnummer.
Der API-Server bestimmt, ob das Update möglich ist oder nicht, basierend darauf, ob die von update
gesendete Versionsnummer und die Versionsnummer der Ressource, für die das Update angefordert wurde, identisch sind.
Wenn es aktualisiert wird, wird die Versionsnummer der entsprechenden Ressource erhöht.
Last-Modified / If-Unmodified-Since Der Aktualisierungsablauf und der optimistische Sperrablauf sind in der folgenden Abbildung dargestellt. Der Client gibt eine Liste mit dem Header "Last-Modified" zurück, um alle Ressourcen abzurufen, die dem entsprechenden Endpunkt zugeordnet sind. Fügen Sie zu diesem Zeitpunkt das Datum und die Uhrzeit der letzten Änderung der Ressource in den Header "Zuletzt geändert" ein. Der API-Server vergleicht das Datum und die Uhrzeit, die mit "If-Unmodified-Since" (= der Wert von "Last-Modified") gesendet wurden, mit dem Datum und der Uhrzeit der letzten Aktualisierung der Ressource, für die die Aktualisierungsanforderung gestellt wurde, und bestimmt, ob die Aktualisierung möglich ist oder nicht. .. (Wenn das Datum und die Uhrzeit der letzten Aktualisierung der Ressource neuer sind, wird davon ausgegangen, dass sie nicht aktualisiert werden kann.)
So erreichen Sie eine optimistische Sperre | verdienen | Fehler |
---|---|---|
If-Match-Header und ETag-Header | ・ RESTful Lösung | ・ Die Anzahl der Anfragen erhöht sich |
ETags in der Ergebnisentität | ・ Perfekter optimistischer Rock | -Informationen, die dem HTTP-Header hinzugefügt werden sollen, werden in das Geschäftsobjekt übernommen |
Versionsnummer | ・ Perfekter optimistischer Rock | -Informationen, die dem HTTP-Header hinzugefügt werden sollen, werden in das Geschäftsobjekt übernommen |
Last-Modified / If-Unmodified-Since | ・ Da es schon lange verwendet wird, hat es eine nachgewiesene Erfolgsbilanz. ・ Beeinträchtigt keine Geschäftsobjekte ・ Einfach zu implementieren ・ Keine weiteren Anforderungen außer Aktualisierungsanforderungen erforderlich |
-Wenn die API-Seite aus mehreren Instanzen besteht, ist eine strikte Zeitsynchronisation erforderlich. |
Die folgende Quelle implementiert die Listenerfassung und -aktualisierung mit dem Endpunkt "optimistic / etag". https://github.com/nannany/optimistic-lock-demo Die ETag-Generierung erfolgt mit sha256 wie folgt.
package nannany.optimistic.demo.util;
import com.google.common.hash.Hashing;
import static java.nio.charset.StandardCharsets.UTF_8;
public final class DemoUtils {
@SuppressWarnings("UnstableApiUsage")
public static String getHash(String origin) {
return Hashing.sha256().hashString(origin, UTF_8).toString();
}
}
Wie im folgenden GIF gezeigt, ist die Aktualisierung erfolgreich, wenn die ETag-Werte übereinstimmen, und wenn sie nicht übereinstimmen, wird 409 zurückgegeben.
Die folgende Quelle implementiert die Listenerfassung und -aktualisierung mit dem Endpunkt "optimistic / lastModify". https://github.com/nannany/optimistic-lock-demo Das Datum und die Uhrzeit der Erfassung der Liste werden am Datum und der Uhrzeit der letzten Aktualisierung eingegeben, und es wird eine optimistische Sperrung durchgeführt, um festzustellen, ob danach Aktualisierungen an der Ressource vorgenommen wurden.
Wie im folgenden GIF gezeigt, ist die Aktualisierung erfolgreich, wenn das Datum und die Uhrzeit der letzten zu aktualisierenden Ressource der zu aktualisierenden Ressource vor dem Datum und der Uhrzeit liegen, die im Header "If-Unmodified-Since" empfangen wurden. Andernfalls wird 412 zurückgegeben.
Betrachten wir einige der optimistischen Sperrtechniken, die in Zalando nicht spezifiziert sind.
In Zalando beide der beiden oben genannten Methoden Vorteile: Perfekter optimistischer Rock Nachteil: Informationen, die dem HTTP-Header hinzugefügt werden sollen, gelangen in das Geschäftsobjekt Es gibt keinen klaren Unterschied zwischen Vor- und Nachteilen. (Ich bin mir nicht sicher über den perfekten optimistischen Rock, da es keine detaillierte Erklärung gibt)
Wir glauben, dass die Unterschiede zwischen den Vor- und Nachteilen dieser beiden Methoden die folgenden zwei Punkte sind.
Bei beiden Methoden enthalten die an den Client zurückgegebenen Listeninformationen Elemente (ETag und Version) außerhalb des Geschäftsobjekts. Auf der API-Serverseite kann der Wert von ETag jedoch einen Wert des Geschäftsobjekts als Startwert generieren, dh es ist nicht erforderlich, den Wert von ETag zu speichern, während der Wert der Version auf der API-Serverseite gespeichert wird. Muss erledigt werden. Wenn Sie sich dagegen entscheiden, den ETag-Wert nicht auf der API-Serverseite beizubehalten, müssen Sie den ETag jedes Mal berechnen, wenn Sie die Listeninformationen erhalten. Daher müssen Sie prüfen, ob er hinsichtlich der Leistung in Ordnung ist. Korrekt.
Wenn ich darüber nachdenke, wie man die Persistenzinformationen vereinfacht und was man mit der Leistung macht, denke ich, dass dies ein Verdienst und ein Fehler ist.
Die Versionsnummer ist im Grunde ein Wert, der bei jedem Update um 1 erhöht wird, und es ist relativ einfach, die Versionsnummer zu erraten, die aktualisiert werden kann. Andererseits erfordert das Ableiten des Werts von ETag den für die ETag-Generierung verwendeten Algorithmus, den beim Generieren von ETag verwendeten Startwert und den Wert des Startwerts zum Zeitpunkt der Aktualisierung, was schwieriger ist als das Ableiten der Versionsnummer. Es gilt als.
Wenn ich an Sicherheit denke, denke ich, dass dies ein Verdienst und ein Fehler ist.
Wenn Sie in "Last-Modified / If-Unmodified-Since" den Wert des Headers "If-Unmodified-Since" von der Clientseite aus neu schreiben und die Zukunft weit voraus angeben (z. B. 31. Dezember 9999), die Ressource Selbst wenn der Wert seit "Zuletzt geändert" aktualisiert wurde, kann er von oben aktualisiert werden.
Aus Sicherheitsgründen halte ich "Last-Modified / If-Unmodified-Since" daher nicht für stark.
Ich habe mir die in Zalando aufgeführte optimistische Sperrmethode angesehen, aber am Ende dachte ich, ich hätte keine andere Wahl, als mir eine Methode auszudenken, die den Anforderungen des von mir erstellten Systems entspricht. Die Tatsache, dass Zalando auch vier Methoden einführt, bedeutet, dass nicht für jedes System die beste optimistische Methode zur Implementierung von Sperren entwickelt wurde.
Anstatt darüber nachzudenken, wie die optimistische Sperre der RESTful-API von 0 implementiert werden soll, wird empfohlen, sie unter Bezugnahme auf die Beschreibung von Zalando usw. zu implementieren und die eingeführten Vor- und Nachteile auf Ihr eigenes System anzuwenden. Ist es nicht eine realistische Lösung?
Zalando Tagebuch der Wissenschaftsstudenten RFC7232
Recommended Posts