Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

nginx 配置之 304 缓存

  304 缓存通常是使用 ETag 或 If-Modified-Since,而这两个头的处理都是 nginx 自带支持的。在 nginx 中有 etag 和 if_modified_since 两个指令用于配置这两个东西,而且它们都是默认开启的。但是还是有不少细节值得注意,比如 ETag 的计算方式、Last-Modified 的比对方式等。
  nginx 自带的 ETag 功能其实是非常弱的,它支持将文件最后编辑时间戳的 16 进制和文件的字节数用「-」连接起来,并且在外面包个双引号而已(这部分代码可以在 ngx_http_core_module.c#L1800-L1803 中找到)。所以 nginx 自带的 ETag 和数据本身关,甚至多个文件可以拥有同一个 ETag 值。比如这样:

  另外关键的问题是 Last-Modified 的比对方式。if_modified_since 指令有三个取值,off 是关闭谁都知道。exact 是默认值,严格匹配时间,只要有变化,无论如何变化都算变化。而 before 的取值会将两个时间做比较,只有当服务器的文件比客户端新时才会更新。
  这里有一个值得思考的问题,客户端的文件版本什么情况下才会别服务器还新?一种情况是服务器是一个集群,更新文件时部分服务器先生效,用户访问新的服务器后又去访问旧的服务器,所以客户端的资源版本比服务器端还新。如果是为了解决这个问题,使用 before 确实更好。这样客户端就不会因为服务器资源不同步而来回切换自己缓存的资源,造成传输冗余。但并不是 before 就比 exact 好,考虑到代码可能回滚,如果使用 before 的话,一旦客户端缓存了新版有 Bug 的程序,服务器即使回滚代码,由于请求时的 Last-Modified 比服务器还新,服务器依然会 304。这可能导致回滚无法生效的情况。当然,这个问题是可以解决的。因为回滚代码未必是使用旧的文件,或者如果真觉得有问题甚至可以在回滚后把所有资源文件 touch 一下来更新 Last-Modified。所以综合上述,如果代码发布和回滚都处于我可控的范围内,我会更倾向于用 before。
网名:
3.84.186.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^