• 欢迎访问web前端中文站,JavaScript,CSS3,HTML5,web前端demo
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏web前端中文站吧

Nginx HTTP缓存设置

JAVA web前端中文站 2年前 (2017-05-15) 930次浏览 已收录 0个评论

Nginx 提供了 expires、etag、if-modified-since 指令来实现浏览器缓存控制。

更多精彩内容请看 web 前端中文站
http://www.lisa33xiaoq.net 可按 Ctrl + D 进行收藏

expires

如果我们使用 Nginx 作为静态资源服务器,那么可以使用 expires 进行缓存控制。

 location /img {   alias /export/img/;   expires 1d; }

当我们访问静态资源时,如 https://www.lisa33xiaoq.net/wp-content/uploads/2016/04/gaollg1.gif,将得到类似如下的响应头。

Nginx HTTP 缓存设置

对于静态资源会自动添加 ETag,可以通过添加 etag off 指令禁止生成 ETag。如果是静态文件,那么 Last-Modified 值为文件的最后修改时间。Expires 是根据当前服务器系统时间算出来的。如上 Nginx 配置的计算逻辑(实际计算逻辑比这个多,具体参考官方文档)。

 if (expires == NGX_HTTP_EXPIRES_ACCESS||r->headers_out.last_modified_ time == -1) {    max_age = expires_time;    expires_time += now; }

if-modified-since

此指令用于指定 Nginx 如何拿服务端的 Last-Modified 和浏览器端的 if-modified- since 时间进行比较,默认“if_modified_since exact”表示精确匹配,也可以使用“if_modified_since _before”表示只要文件的最后修改时间早于或等于浏览器端的 if-modified-since 时间,就返回 304。

nginx proxy_pass

使用 Nginx 作为反向代理时,请求会先进入 Nginx,然后 Nginx 将请求转发给后端应用,如下图所示。

Nginx HTTP 缓存设置

首先配置 upstream。

 upstream backend_tomcat {    server 192.168.61.1:9080max_fails=10 fail_timeout=10s weight=5; }

接着配置 location

 location = /cache {    proxy_pass http://backend_tomcat/cache$is_args$args; }

接下来,我们可以通过如 https://www.lisa33xiaoq.net/?p=1144 访问 Nginx,Nginx 会将请求转发给后端 Java 应用。也就是说 Nginx 只是做了相关的转发(负载均衡),并没有对请求和响应做什么处理。
假设对后端返回的过期时间需要调整,可以添加 Expires 指令到 location。

 location = /cache {    proxy_pass http://backend_tomcat/cache$is_args$args;    expires 5s; }

然后再请求相关的 URL,将得到如下响应。

Nginx HTTP 缓存设置

过期时间相关的响应头被 Expires 指令更改了,但是 last-modified 是没有变的。
即使我们更改了缓存过期头,但 Nginx 自己没有对这些内容做代理层缓存,每次请求还是要到后端验证的,假设在过期时间内,这些验证在 Nginx 这一层验证就可以了,不需要到后端验证,这样可以减少后端很大的压力。即整体流程如下。

  1. 浏览器发起请求,首先到 Nginx,Nginx 根据 URL 在 Nginx 本地查找是否有代理层本地缓存。
  2. Nginx 没有找到本地缓存,则访问后端获取最新的文档,并放入到 Nginx 本地缓存中,返回 200 状态码和最新的文档给浏览器。
  3. Nginx 找到本地缓存,首先验证文档是否过期(Cache-Control:max-age=5),如果过期,则访问后端获取最新的文档,并放入 Nginx 本地缓存中,返回 200 状态码和最新的文档给浏览器;如果文档没有过期,即 if-modified-since 与缓存文档的 last-modified 匹配,则返回 304 状态码给浏览器。

内容不需要访问后端,即不需要后端动态计算/渲染等,直接 Nginx 代理层就把内容返回了,速度更快,内容越接近于用户速度越快。像 ApacheTraffic Server、Squid、Varnish、Nginx 等技术都可以用来进行内容缓存。还有 CDN 技术就是用来加速用户访问的。

Nginx HTTP 缓存设置

即用户首先访问到全国各地的 CDN 节点(使用如 ATS、Squid 实现),如果 CDN 没命中,则会回源到中央 Nginx 集群,该集群做二级缓存,如果没有命中缓存(该集群的缓存不是必须的,要根据实际命中情况等决定),则最后回源到后端应用集群。

Nginx 代理层缓存

Nginx 代理层缓存配置。HTTP 模块配置:

 proxy_buffering                  on; proxy_buffer_size                4k; proxy_buffers                    5124k; proxy_busy_buffers_size          64k; proxy_cache_path                 /export/cache/proxy_cachelevels=1:2 keys_zone=cache:512m inactive=5m max_size=8g use_temp_path=off; #proxy timeout proxy_connect_timeout            3s; proxy_read_timeout               5s; proxy_send_timeout               5s;

proxy_cache_path 指令配置。

levels=1:2:表示创建两级目录结构,缓存目录的第一级目录是 1 个字符,第二级目录是 2 个字符,比如/export/cache/proxy_cache/7/3c/,如果将所有文件放在一级目录下的话,文件量很大,会导致文件访问慢。
keys_zone=cache:512m :设置存储所有缓存 key 和相关信息的共享内存区,1M 大约能存储 8000 个 key。
inactive=5m :inactive 指定被缓存的内容多久不被访问将从缓存中移除,以保证内容的新鲜,默认为 10 分钟。
max_size=8g :最大缓存阀值,“cache manager”进程会监控最大缓存大小,当缓存达到该阀值时,该进程将从缓存中移除最近最少访问的内容。
use_temp_path:如果为 on,则内容首先被写入临时文件(proxy_temp_path ),然后重命名到 proxy_cache_path 指定的目录;如果设置为 off,则内容直接被写入到 proxy_cache_path 指定的目录,如果需要 cache 建议 off,则该特性是 1.7.10 提供的。

nginx 的 location 配置

 location = /cache {      proxy_cache cache;      proxy_cache_key$scheme$proxy_host$request_uri;      proxy_cache_valid 200 5s;      proxy_passhttp://backend_tomcat/cache$is_args$args;     add_header cache-status$upstream_cache_status; }

缓存相关配置

proxy_cache:指定使用哪个共享内存区存储缓存信息。
proxy_cache_key :设置缓存使用的 key,默认为完整的访问 URL,根据实际情况设置缓存 key。
proxy_cache_valid :为不同的响应状态码设置缓存时间。如果是 proxy_cache_valid5s,则 200、301、302 响应都将被缓存。

proxy_cache_valid 不是唯一设置缓存时间的,还可以通过如下方式(优先级从上到下)。

  1. 以秒为单位的“X-Accel-Expires”响应头来设置响应缓存时间。
  2. 如果没有“X-Accel-Expires”,则可以根据“Cache-Control”、“Expires”来设置响应缓存时间。
  3. 否则,使用 proxy_cache_valid 设置缓存时间。

如果响应头包含 Cache-Control:private/no-cache/no-store、Set-Cookie 或者只有一个 Vary 响应头且其值为*,则响应内容将不会被缓存。可以使用 proxy_ignore_headers 来忽略这些响应头。

add_header cache-status $upstream_cache_status 在响应头中添加缓存命中的状态。
HIT:缓存命中,直接返回缓存中内容,不回源到后端。
MISS:缓存未命中,回源到后端获取最新的内容。
EXPIRED:缓存命中但过期了,回源到后端获取最新的内容。
UPDATING:缓存已过期但正在被别的 Nginx Worker 进程更新,配置了 proxy_cache_use_stale updating 指令时会存在该状态。
STALE:缓存已过期,但因后端服务出现了问题(比如后端服务挂了)返回过期的响应,配置了如 proxy_cache_use_stale error timeout 指令后会出现该状态。
REVALIDATED:启用 proxy_cache_revalidate 指令后,当缓存内容过期时,Nginx 通过一次 if-modified-since 的请求头去验证缓存内容是否过期,此时会返回该状态。
BYPASS:proxy_cache_bypass 指令有效时,强制回源到后端获取内容,即使已经缓存了。

proxy_cache_min_uses

用于控制请求多少次后响应才被缓存。默认“proxy_cache_min_uses1;”,如果缓存热点比较集中、存储有限,则可以通过修改该参数来来减少缓存数量和写磁盘次数。

proxy_no_cache

用于控制什么情况下响应不被缓存。比如配置“proxy_no_cache$args_nocache”,如果带的 nocache 参数值至少有一个不为空或者为 0,则响应将不被缓存。

proxy_cache_bypass

类似于 proxy_no_cache,但是,其控制什么情况不使用缓存的内容,而是直接到后端获取最新的内容。如果命中,则$upstream_cache_status 为 BYPASS。

proxy_cache_use_stale

当对缓存内容的过期时间不敏感,或者后端服务出问题时,即使缓存的内容不新鲜也总比返回错误给用户强(类似于托底),此时可以配置该参数,如“proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504”,即如果出现超时、后端连接出错、500、502、503 等错误时,则即使缓存内容已过期也先返回给用户,此时$upstream_cache_status 为 STALE。还有一个 updating 表示缓存已过期但正在被别的 Nginx Worker 进程更新,但先返回了过期内容,此时$upstream_cache_status 为 UPDATING。

proxy_cache_revalidate

当缓存过期后,如果开启了 proxy_cache_revalidate,则会发出一次 if-modified-since 或 if-none-match 条件请求,如果后端返回 304,则此时$upstream_cache_status 为 REVALIDATED,我们将得到两个好处,节省带宽和减少写磁盘的次数。

proxy_cache_lock

当多个客户端同时请求同一份内容时,如果开启 proxy_cache_lock(默认 off),则只有一个请求被发送至后端。其他请求将等待该请求的返回。当第一个请求返回后,其他相同请求将从缓存中获取内容返回。当第一个请求超过了 proxy_cache_lock_timeout 超时时间(默认为 5s),则其他请求将同时请求到后端来获取响应,且响应不会被缓存(在 1.7.8 版本之前是被缓存的)。启用 proxy_cache_lock 可以应对 Dog-pile effect(当某个缓存失效时,同时有大量相同的请求没命中缓存,而同时请求到后端,从而导致后端压力太大,此时限制一个请求去拿即可)。
proxy_cache_lock_age 是 1.7.8 新添加的,如果在 proxy_cache_lock_age 指定的时间内(默认为 5s),最后一个发送到后端进行新缓存构建的请求还没有完成,则下一个请求将被发送到后端来构建缓存(因为 1.7.8 版本之后,proxy_cache_lock_timeout 超时之后返回的内容是不缓存的,需要下一次请求来构建响应缓存)。

清理缓存

有时缓存的内容是错误的,需要手工清理,Nginx 企业版提供了 purger 功能,对于社区版 Nginx 可以考虑使用 ngx_cache_purge(https://github.com/FRiCKLE/ ngx_cache_purge)模块进行清理缓存。

 location ~ /purge(/.*) {    allow             127.0.0.1;    deny              all;    proxy_cache_purge cache$1$is_args$args; }

该方法要限制其访问权限,如只允许内网可以访问或者需要密码才能访问。

【注:本文源自网络文章资源,由站长整理发布】


web 前端中文站 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Nginx HTTP 缓存设置
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址