当前位置: 代码迷 >> 综合 >> Openresty/Nginx 缓存设置 - 缓存设置
  详细解决方案

Openresty/Nginx 缓存设置 - 缓存设置

热度:85   发布时间:2024-02-22 14:54:41.0

HTTP 缓存设置

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

expires

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

location ~ ^/images/* {root /Users/xuefeihu/hugege/code-sublime;expires 365d;
}

当我们访问 http://moguhu.com/images/83131d36-0170-42d5-b4d5-c606674f2376.png 时,得到如下响应头。

Openresty/Nginx 缓存设置

 

if-modified-since

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

proxy_pass 流程

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

代理层缓存

HTTP 模块配置

proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 512 4k;
proxy_busy_buffers_size 64k;
proxy_cache_path /export/cache/proxy_cache levels=1:2 keys_zone=cache:512m inactive=5m max_size=8g;
#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 提供的。

proxy_cache 配置

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

上述的配置详解如下:

  • proxy_cache:指定使用哪个共享内存区存储缓存信息。
  • proxy_cache_key:设置缓存使用的 key,默认为完整的访问 URL。
  • proxy_cache_valid:为不同的响应状态码设置缓存时间。如果是 proxy_cache_valid 5s ,则 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-storeSet-Cookie 或者只有一个 Vary: *,则响应内容将不会被缓存。可以使用 proxy_ignore_headers 来忽略这些响应头。

  • add_header cache-status $upstream_cache_status 在响应头中添加缓存命中的状态。
  1. HIT:缓存命中,直接返回缓存中内容,不回源到后端。
  2. MISS:缓存未命中,回源到后端获取最新的内容。
  3. EXPIRED:缓存命中但过期了,回源到后端获取最新的内容。
  4. UPDATING:缓存已过期但正在被别的 Nginx Worker 进程更新,配置了 proxy_cache_use_stale updating 指令时会存在该状态。
  5. STALE:缓存已过期,但因后端服务出现了问题(比如后端服务挂了)返回过期的响应,配置了如 proxy_cache_use_stale error timeout 指令后会出现该状态。
  6. REVALIDATED:启用 proxy_cache_revalidate 指令后,当缓存内容过期时,Nginx 通过一次 if-modified-since 的请求头去验证缓存内容是否过期,此时会返回该状态。
  7. BYPASS:proxy_cache_bypass 指令有效时,强制回源到后端获取内容,即使已经缓存了。
  • proxy_cache_min_uses:用于控制请求多少次后响应才被缓存。默认'proxy_cache_min_uses 1;',如果缓存热点比较集中、存储有限,则可以通过修改该参数来来减少缓存数量和写磁盘次数。
  • 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 超时之后返回的内容是不缓存的,需要下一次请求来构建响应缓存)。

小节

  • 只缓存 200 状态码的响应,如系统错误跳转至 302,此时缓存 302 就不对了。
  • 有些页面不需要强一致性,可以进行几秒的缓存。比如商品详情页的库存。
  • 静态资源文件(JS/CSS/IMAGE)可以缓存较长时间,如 1 个月、1 年等。

参考:《亿级流量网站架构核心技术》

转自:https://www.shangyouw.cn/shezhi/arc37537.html