5

基于Http的ETags和If-Modified-Since实现乐观并发性

 1 year ago
source link: https://www.jdon.com/67023.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

基于Http的ETags和If-Modified-Since实现乐观并发性

HTTP的特点是ETags和条件性请求,并启用乐观的并发性。

ETag
ETag(又称实体标记entity-tag)解决了 "丢失更新 "的问题,即一个API的两个客户端已经收到了一个实体的版本的数据。但是,另一个客户端在另一个客户端之前更新了该实体:第二个更新导致第一个更新 "丢失"。

ETag通过用实体标签(表示法的哈希值、版本等)对资源进行版本管理来解决意外的覆盖。当客户端请求一个资源时,服务器可以在响应中包括一个带有实体标签值的ETag验证器标头域。

资源的URI与该实体标记一起构成了一个实体的特定版本的标识符。

当客户端请求对实体进行修改时,它包括实体标签作为基础版本,并带有一个条件头域(如If-Match)。服务器响应412(前提条件失败),客户端可以检索最新版本,重新应用他们的修改,并重新发送。

即使你使用日期和时间,HTTP也为你提供了其他涉及修改日期的前提条件头域。

If-Unmodified-Since和If-Modified-Since
If-Unmodified-Since和If-Modified-Since前提条件标头域允许你传递修改日期的前提条件,使请求成为有条件的。当前提条件没有满足时,412(前提条件失败)状态代码将出现在响应中,或者对于GET或HEAD,304(未修改)状态代码将出现在响应中。

在有条件的请求中,支持修改日期的资源的初始GET将包括一个Last-Modified头域验证器。

Last-Modified验证器的形式是HTTP-date.。

RFC 7232,HTTP 1.1规范,第2.3节描述了实体标签:

实体标签是一个不透明的验证器,用于区分同一资源的多种表现形式,无论这些多种表现形式是由于资源状态随时间的变化、内容协商导致多种表现形式同时有效,还是两者都是如此。

这意味着ETag值取决于内容类型,所以同一资源的两个不同的输出数据应该有不同的ETag值(例如,一个使用gzip编码,一个则没有使用压缩。)

这也意味着ETag值对请求者来说是不透明的,但确实指出了ETag的意图之一,即由于缺乏准确性而成为使用日期-时间戳的替代品。

PATCH
将PATCH与JSONPatch这样的东西一起使用,似乎可以通过提供更细化的变化内容来帮助缓解冲突。

从技术上讲是的,要实现这一点并不容易。

ETag指定了整个资源的那个版本的标签,而不是任何一个字段。

虽然比较一个资源的两个版本之间的变化(记住这些版本可能不相邻)可能是处理这个问题的一种技术,但在同一资源的任意版本之间创建delta 是不容易的。你可以引入这类东西:类似事件溯源的东西可能会实现这一点

但请记住,资源的属性之间可能存在相互依赖的关系,仅仅因为当前的请求改变了一个自资源被检索以来没有改变的属性,并不意味着仍然存在冲突。

Last-Modified
请记住,Last-Modified使用HTTP-date格式,所以Last-Modified只支持秒级的粒度。如果有多个来源服务器,可能需要超过第二个粒度的数据才能100%准确。

If-Unmodified-Since
If-Unmodified-Since与PUT、POST、DELETE和PATCH等状态改变方法一起使用,以避免意外的覆盖(丢失更新)。If-Unmodified-Since的前提条件是,只有当这个实体在提供的日期时间后没有改变时,才会更新它。使用If-Unmodified-Since来避免丢失更新的问题,当第二粒度不是问题时。

If-Modified-Since
当与GET或HEAD一起使用时,If-Modified-Since头域施加了一个前提条件,即如果识别的资源的修改日期不比提供的日期更近,则以304(未修改)进行响应,而不是以实体表示。使用If-Modified-Since来避免重新传输相同的数据。

409 (冲突)
409 (Conflict)听起来像是对有条件的PUT/POST/PATCH请求的适当响应,但412 (Precondition Failed)是预期的。当资源的当前状态意味着服务器不能改变它时,应该使用响应状态代码409。另外,如果你选择不使用HTTP的先决条件功能,并且在实体的表示中包含了一些用于版本管理的东西(比如最后修改日期,见上文),那么409(冲突)是合适的,以表示潜在的意外覆盖或丢失更新。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK