LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

Nginx百万并发下性能优化之前端静态缓存、后端动态缓存实践

admin
2025年12月27日 8:8 本文热度 1070

0x00 前言简述

描述:在现代网站架构中,随着Web应用的复杂性不断增加,页面加载速度和响应时间直接影响用户的留存率和满意度,为了提高性能和用户体验,缓存技术被广泛应用。Nginx 作为一个高性能的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,其内置的缓存机制是其核心功能之一,本文将由浅入深探讨浏览器缓存以及 Nginx 在前端、后端(反向代理)缓存的实现原理、指令参数、配置方法以及在生产环境中的应用。

在深入讲解之前,让我们先了解一些现代Web开发中一些缓存(Cache)的基本概念吧,有助于后续理解 Nginx 的缓存机制,以及帮助我们更好的配置前、后端(上游)缓存。

温馨提示:若文章代码块中存在乱码或不能复制,请联系作者,也可通过文末的阅读原文链接,加入知识星球中阅读,原文链接:https://articles.zsxq.com/id_6hpaidhf5l5s.html


缓存的基本概念

缓存的意义

提升性能:减少资源加载时间,加快页面渲染速度。 降低负载:减少对服务器的请求次数,节省带宽资源。 优化体验:快速加载的页面能够提高用户满意度和留存率。


缓存的分类

作者将现代Web开发缓存分为两大类,即前端缓存(Browser Cache)后端缓存(Server/Proxy Cache),两种方式各有优势,适用于不同的场景。

  • 前端缓存:是指将静态资源(如HTML、CSS、JavaScript、图片、字体等)存储在浏览器或客户端的本地存储或中间代理服务器(如 CDN)中,当用户再次访问相同资源时,可以直接从本地快速加载,而无需重新从服务器下载,从而减少网络延迟和带宽消耗。

  • 后端缓存: 是指将动态资源(如首页广告JSON列表、导航栏JSON列表)存储在Web服务器(如Nginx)或代理服务器(如 CDN)上实现的缓存机制,当用户访问特定的URL时,根据缓存策略设置可以直接从缓存中获取响应数据,而无需访问后端服务器从数据库再读取数据,从而减少服务器、数据库负载和响应时间,提高数据传输效率。


缓存的实现方式

前端缓存(Browser Cache)

对于前端(浏览器)缓存的实现,主要有以下几种方式,其中 HTTP 缓存头是实现HTTP缓存最常用的方式,也是 Nginx 实现前端缓存的主要方式。

1.HTTP缓存头:通过设置 HTTP 响应头的Cache-ControlExpiresETag、 Last-Modified 等指令,控制浏览器缓存行为,如决定是否从本地加载资源。

  • Cache-Control:是 HTTP/1.1 标准中控制缓存策略的核心响应头,比 Expires 头更精确和强大, 正确配置 Cache-Control 可以显著提升网站性能,减少服务器负载,改善用户体验。


    重新验证和重新加载指令:


    • must-revalidate: 过期后必须向服务器验证,不能使用过期资源
    • proxy-revalidate: 仅要求代理服务器重新验证
    • immutable: 资源永不变更,客户端无需重新验证

        过期时间指令

    • max-age=<seconds>: 资源在客户端的缓存最大有效时间。
    • s-maxage=<seconds>: 仅适用于共享缓存(如CDN),表示资源在代理服务器上的最大有效时间。
    • stale-while-revalidate=<seconds>: 允许资源在过期后继续使用,但在后台重新验证其有效性。
    • stale-if-error=<seconds>: 在遇到错误时,允许资源在过期后继续使用一段时间。

      可缓存性指令(是否可缓存):
    • public:资源可以被任何对象缓存(客户端、代理服务器、CDN等), 适用于静态资源(JS、CSS、图片)
    • private:资源只能被客户端缓存,代理服务器不能缓存,适用于用户个人信息、购物车内容
    • no-cache: 可以缓存,但每次使用前必须向服务器验证,适用于经常变动的数据
    • no-store: 禁止任何缓存,每次都从服务器获取,适用于敏感数据或临时数据
    • no-transform: 禁止代理服务器修改内容(如压缩图片)


# public vs private
# 可以被任何中间服务器缓存
Cache-Control: public, max-age=3600
# 只能被最终用户浏览器缓存
Cache-Control: private, max-age=3600

# s-maxage 控制共享缓存
# 客户端缓存1小时,CDN缓存10分钟
Cache-Control: public, max-age=3600, s-maxage=600

# immutable 永不变更,主要针对带版本hash的资源或已确定永不变更的资源
Cache-Control: public, max-age=31536000, immutable

# must-revalidate 1天内有效,过期后必须验证
Cache-Control: public, max-age=86400, must-revalidate

# stale-while-revalidate 过期后60秒内仍可使用,同时后台更新
Cache-Control: max-age=3600, stale-while-revalidate=60

# stale-if-error 容错处理,300秒内可使用过期缓存
Cache-Control: max-age=3600, stale-if-error=300

# 生产环境中常用组合示例:
Cache-Control: max-age=3600, stale-while-revalidate=60, stale-if-error=300
  • Expires:资源的过期时间,用于指示资源何时失效(绝对时间), 例如Expires: Tue, 21 Jan 2025 07:28:00 GMT

  • ETag:资源的唯一标识,用于验证资源内容是否更改, 例如ETag: "12345"表示当前版本为"12345"。

    • If-None-Match:在请求时,通过If-None-Match头部携带资源的ETag值,服务器会对比该值与当前资源版本是否一致。如果一致(即内容未更改),则返回304 Not Modified状态码,告诉浏览器直接使用本地缓存;如果不一致,则返回200状态码,并携带新的资源内容。
  • Last-Modified:资源的最后修改时间,用于验证资源是否过期, 例如Last-Modified: Tue, 21 Jan 2025 07:28:00 GMT

    • If-Modified-Since:在请求时,通过If-Modified-Since头部携带资源的最后修改时间,服务器会对比该值与当前资源是否一致。如果一致(即内容未更改),则返回304 Not Modified状态码,告诉浏览器直接使用本地缓存;如果不一致则同样返回200状态码,并携带新的资源内容。

温馨提示:HTTP 缓存响应头优先级如下 Cache-Control > Expires > 启发式缓存

温馨提示:Pragma 是 HTTP/1.0 时代的遗留头,用于向后兼容,在现代 HTTP/1.1 中,它的功能基本被 Cache-Control 头取代,但在某些情况下仍然有用,了解即可。

# HTTP/1.0 (1996年)
Pragma: no-cache
Expires: 0

# HTTP/1.1 (1999年) - 推荐使用
Cache-Control: no-cache, no-store, must-revalidate


2.本地存储:利用浏览器提供的本地存储机制(如Cookies、LocalStorage和IndexedDB)来缓存数据,适用于需要持久化保存的数据。

// 存储数据
localStorage.setItem('userData'JSON.stringify(data));

// 读取数据
const userData = JSON.parse(localStorage.getItem('userData'));


3.Service Worker:通过编写JavaScript代码,在浏览器后台运行一个常驻的脚本(Service Worker),它可以拦截并处理网络请求,从而实现更灵活的缓存策略,例如离线访问、动态缓存和资源预加载等功能,主要应用于对于一些实时性要求不高、可离线使用的Web应用的场景。

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('my-cache').then((cache) => {
      return cache.addAll(['/index.html''/styles.css''/script.js']);
    })
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      return response || fetch(event.request);
    })
  );
});


4.CDN(内容分发网络):将静态资源托管到CDN,并配置CDN的缓存策略,通过在全球各地部署节点,将静态资源缓存到离用户最近的服务器上,以实现快速访问,通常用于高并发场景,但数有一定的成本。


实践与优化建议:

  • 对于长期不变的静态资源(如图片、字体、视频),通过设置较长的缓存时间(如一周或更久,如:Cache-Control:max-age=604800, public),或通过CDN加速分发(同样需要设置缓存机制)。

  • 对于可能变化的静态资源(如CSS、JavaScript),在文件名中添加哈希值(如 styles.[hash].css 推荐)或者v参数(如styles.css?v=2.1.0)来实现缓存版本控制。

  • 对于经常变化的资源(如 HTML 文件),可以采用协商缓存(如ETagLast-Modified),在资源更新时通过HTTP响应头通知浏览器重新加载。

  • 对于本地存储机制(LocalStorage 和 IndexedDB)来缓存数据,可通过 Service Worker手动定期清理过期的缓存资源,避免占用过多存储空间。

  • 因为不同浏览器对缓存策略的支持和实现可能存在差异,因此在开发调试时,应使用浏览器开发者工具(如Chrome DevTools)监控缓存命中率,调试缓存策略的有效性和兼容性。


后端缓存(Server/Proxy Cache)

随着微服务架构的快速发展,动态资源缓存成为了提高系统性能和响应速度的关键;通过后端缓存,我们可以在内存中存储经常访问的数据或计算结果,避免重复查询数据库或其他耗时操作,从而大大减少系统负载并缩短用户等待时间。

对于后端缓存(这里特指非静态资源,如 API 接口返回的数据)的实现,主要有以下几种方式,当然 Nginx 作为高性能的web服务器,主要是通过反向代理利用其内置的缓存功能来缓存静态文件、动态内容或其他类型的响应,例如使用proxy_cache_path指令定义缓存目录及参数,并通过location块内的proxy_cache指令启用缓存和使用proxy_cache_key进行缓存策略的设置,此处简单有个印象即可,后续会详细讲解。


1.代理缓存: 利用类似于 Nginx 的反向代理缓存,通过配置 Nginx 服务器或使用其他反向代理软件(如 Varnish、HAProxy)来实现。

2.后端服务缓存:利用内存缓存(如Redis、Memcached)或本地内存来存储数据,适用于需要快速访问且数据量不大的场景。

  • Redis 是一个开源的键值存储系统,同时也提供了多种数据结构如字符串、哈希表、列表、集合和有序集合等,支持发布/订阅模式的消息队列功能以及lua脚本语言。(常用)
  • Memcached 是一个高性能的分布式内存对象缓存系统,用于存储数据以减少对数据库的访问次数。

3.CDN: 除了针对静态资源的前端缓存,CDN同样可以用于动态内容的分发和缓存。通过配置CDN的缓存规则,可以将动态内容(如API响应,一段时间情况下不变的、或对实时性不高的场景)缓存在离用户最近的边缘节点上,减少回源请求次数,提高访问速度。

至此,我们对前端缓存和后端缓存的实现方式有了一个基本的了解,若有不全还请各位看友大佬在评论区评论一下,接下来我们将深入探讨 Nginx 在这两种场景下的具体实现,以及前端缓存和后端缓存的结合使用,进一步提升Web应用的性能。


0x01 Nginx 中前端缓存指令浅析与实践

在讲解 Nginx 前端缓存之前,我们先回顾一下浏览器缓存与服务端交互流程:

  1. 浏览器发起请求,若未命中本地缓存,浏览器将发起请求到服务器。
  2. 判断是否命中本地缓存以及是否过期,若命中且未过期,则直接从本地缓存加载资源。
  3. 若若验证缓存过期状态,首先通过 Etag 或 Last-Modified 验证资源是否更新,若未更新则返回304状态码(减少 Nginx 与 上游服务器之间的流量消耗)直接从本地缓存加载资源。
  4. 若资源更新,则返回200状态码及新的内容。
  5. 请求响应,并更新本地缓存。
  6. 最后呈现页面给浏览器。

weiyigeek.top-浏览器缓存机制图

其次,在图中我们看到在判断 EtagLast-Modified 时分别会向服务器端发起带有 if-None-Match 和 if-Modified-Since 请求头的请求,

Etag 是 HTTP 响应头中用于表示资源内容的唯一标识符,可让缓存更高效,若内容未发生改变服务器不需要发送完整的响应体,返回 304 响应码,减少了带宽的消耗。若内容发生了变换,则有助于防止资源的同时更新相互覆盖("空中碰撞"),另外使用 W/"weak" 前缀表示弱校验器,即允许内容语义相同但字节表示可能不同,大小写敏感,其特别适合内容交付网络(CDN)和反向代理场景,可以在内容有微小变动时仍有效利用缓存。

  • If-None-Match 请求头是与 Etag 相关联的,它是一个条件式请求首部,对于 GET 和 HEAD 请求,服务器会通过 ETag 值来判断资源是否被修改。如果资源的 ETag 与 If-None-Match 的值匹配,则表示资源未发生变化,服务器将返回304 Not Modified状态码,告诉浏览器直接使用本地缓存;若不匹配则返回200状态码,并携带新的资源内容。另外在某些条件下(如预条件失败),可返回 412 Precondition Failed。

Last-Modified 是指资源的最后修改时间。这两种机制都是为了验证浏览器缓存中的内容是否是最新的,从而决定是直接使用本地缓存还是从服务器重新获取最新数据。

  • If-Modified-Since 请求头是与 Last-Modified 相关联的,它也是一个条件式请求首部。对于 GET 和 HEAD 请求,服务器会通过资源的最后修改时间来判断资源是否被修改,若未修改,返回304 Not Modified,反之返回 200 OK 及完整资源体,当前由 ngx_http_core_module 模块处理,

weiyigeek.top-浏览器缓存响应头图

温馨提示:当 If-None-Match 与 If-Modified-Since 请求头共同使用时,前者的优先级更高,后者将会被忽略,除非服务器不支持前者。


指令参数

  • etag: 开启或关闭 ETag 响应头的生成,默认为开启状态,由 ngx_http_core_module 模块提供。
syntax: etag on | off;
default: etag on;
context: http, server, location

# 源码:"文件最后修改时间-文件字节长度"格式为:
ngx_sprintf(etag->value.data,"%xT-%xO",r->headers_out.last_modified_time, r->headers_out.content_length_n);
  • expires: 启用或禁用添加或修改“Expires”和“Cache Control”响应标头字段,由 ngx_http_headers_module 模块提供。
Syntax: expires [modified] time;
        expires epoch | max | off;
Default: expires off;
Context: http, server, location, ifin location

# 参数说明:
off: 禁用添加或修改 Expires 和 Cache-Control 响应头字段。
modified: 时间计算为文件的最后修改时间和指令中指定的时间之和
time: 指定缓存的有效时间,控制 Cache-Control 字段值,单位秒
  @18h30m :表示当天18小时30分钟,注意会受到时区(北京时间,GMT+8)的影响,max-age 为当前时刻与指定时刻间的差值,
  1d: 表示一天
  1w: 表示一周
  1M: 表示一个月
  1y: 表示一年
  1h: 表示一小时,基于当前时间计算Expires和max-age。
  0: 表示立即过期
  -1: 禁用缓存,等同于 off
epoch: 将“Expires”设置为值“Thu,01 Jan 1970 00:00:01 GMT”,将 “Cache-Control” 设置为 “no-cache”.。
max: 将“Expires”设置为值“Thu,31 Dec 2037 23:55:55 GMT”,将 “Cache-Control” 设置为 “max-age=31536000” ,即 10 年

# 示例演示
expires    24h;
expires    modified +24h;
expires    @24h;
expires    0;
expires    -1;
expires    epoch;
expires    $expires;

# 根据文件类型设置不同的缓存时间
map $sent_http_content_type$expires {
  default         off;
  application/pdf 42d;
  ~image/         max;
}
expires $expires;
  • add_header: 用于添加自定义的响应头,前提是响应代码等于200、201(1.3.10)、204、206、301、302、303、304、307(1.1.16、1.0.13)或308(1.13.0),由同样由 [ngx_http_headers_module] 模块提供。
Syntax: add_header name value [always];
Default: —
Context: http, server, location, if in location

# 参数说明:
  name: 响应头字段名。
  value: 响应头字段值。
  always: 可选参数,表示无论响应状态码为何值都添加该头部。

# 示例
add_header Cache-Control private;
  • add_header_inherit: 允许更改 add_header 指令中指定的值的继承规则,默认情况下,使用标准继承模型,即继承上游的一些响应头,但是自定义响应头将覆盖来自上游(父)响应头。
Syntax: add_header_inherit on | off | merge;
Default: add_header_inherit on;
Context: http, server, location, if in location

# 参数说明:
  on 表示使用标准继承模型,即只在当前级别设置值。
  off 表示禁用继承,即只在当前级别设置值,不向上或向下传递。
  merge 表示启用合并模型,即在当前级别设置值的同时,也向上或向下传递该值。
  • if_modified_since: 允许或禁止处理 If-Modified-Since 请求头,由 ngx_http_core_module 提供。
Syntax: if_modified_since off | exact | before;
Default: if_modified_since exact;
Context: http, server, location

# 参数说明:
  off: 禁用处理 If-Modified-Since 请求头。
  exact: 仅在请求的 If-Modified-Since 值与资源的最后修改时间(Last-Modified)完全匹配时,才处理该请求头。
  before: 在请求的 If-Modified-Since 值早于资源的最后修改时间(Last-Modified)时,则返回 304 。


示例演示

步骤 01.为了演示静态资源缓存,下面使用 git 命令拉取作者主页的静态网站源码到 /usr/local/nginx/html/ 目录中。

cd /usr/local/nginx/html
git clone -depth 1 https://github.com/WeiyiGeek/WeiyiGeek.git -depth 1

# 若网页访问报 403 错误,请执行以下命令更改目录权限:
chown -R nginx:nginx /usr/local/nginx/html/WeiyiGeek


步骤 02.接下来,我们通过配置 Nginx 来实现前端静态资源的缓存。

cd /usr/local/nginx/conf.d/

# 简单配置示例
tee test.conf <<'EOF'
server {
  listen 80;
# 虚拟主机服务器名称
  server_name test.weiyigeek.top;
  charset utf-8;
  default_type text/html;

# 启用 HTTP/2 支持
  http2 on;

# 启用 ETag 支持(实际上不加也可,缺省是开启的)
  etag on;

# 日志文件
  access_log /var/log/nginx/test.log main;
  error_log /var/log/nginx/test.err.log debug;

# 根目录
  root /usr/local/nginx/html/WeiyiGeek;
  location / {
    index index.html;
  }

# 静态资源缓存配置(没有考虑带?v=版本的)
  location ~* \.(jpg|jpeg|png|gif|ico)$ {
    expires 7d;
    # HTTP 1.1 缓存控制
    add_header Cache-Control "public, immutable";
    # HTTP 1.0 缓存控制(旧版本,了解即可)
    add_header Pragma public;
    # 关闭日志记录静态资源(减少日志量)
    access_log off;
  }

# CSS 和 JS 文件 - 为了验证缓存的有效性,这里设置为10秒过期时间,并且必须需要重新验证
  location ~* \.(css|js)$ {
    expires 10s;
    add_header Cache-Control "public,  must-revalidate"# 关键点
    add_header Pragma public;
    access_log off;
  }

# Web字体文件,资源永不变更,客户端无需重新验证
  location ~* \.(woff|woff2|ttf|eot|svg)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    access_log off;
  }

# HTML文件 - 较短缓存或协商缓存,过期后需要重新请求
  location ~* \.html$ {
    expires @17h5m;
    add_header Cache-Control "public, must-revalidate";
  }

# API目录 - 不缓存此目录的资源,由于优先级较高,会覆盖前面定义的静态的缓存配置。
  location ^~ /api/ {
    expires -1;
    add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
    add_header Pragma "no-cache";
  }
}
EOF


步骤 03.执行nginx -s reload重启 Nginx 服务,使用 curl 和 浏览器开发者工具(F12)验证缓存配置是否生效。

# 验证1.验证 HTML 文件缓存配置是否生效
$ curl -s -o /dev/null -D - http://test.weiyigeek.top/index.html
HTTP/1.1 200 OK
Server: nginx/1.29.0
Date: Wed, 24 Dec 2025 08:39:02 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 14408
Last-Modified: Wed, 24 Dec 2025 05:04:27 GMT
Connection: keep-alive
ETag: "694b745b-3848"   # 响应头中的ETag值,用于验证缓存的有效性
Expires: Wed, 24 Dec 2025 17:05:00 GMT  # 响应头中的 Expires 值,表示资源过期时间,配置文件中设置为17点过5分钟
Cache-Control: max-age=30358   # 由于受到时区的影响北京时间为 GMT+8,所以还有将近 8 小时才过期,这一点需要特别注意。
Cache-Control: public, must-revalidate  # 配置文件中设置的缓存控制策略,过期后需要重新请求
Accept-Ranges: bytes

# 验证2.验证API目录中 gif 图片资源缓存配置是否生效
$ ls /usr/local/nginx/html/WeiyiGeek/api/
loading.gif
$ curl -s -o /dev/null -D - http://test.weiyigeek.top/api/loading.gif
HTTP/1.1 200 OK
Server: nginx/1.29.0
Date: Thu, 25 Dec 2025 00:53:12 GMT
Content-Type: image/gif
Content-Length: 37072
Last-Modified: Wed, 24 Dec 2025 05:04:27 GMT
Connection: keep-alive
ETag: "694b745b-90d0"
Expires: Thu, 25 Dec 2025 00:53:11 GMT
Cache-Control: no-cache 
Cache-Control: no-store, no-cache, must-revalidate, max-age=0 # 关键点,API目录的资源不缓存
Pragma: no-cache
Accept-Ranges: bytes

观察 Network 标签的Size列查看缓存状态(memory cache 内存缓存, disk cache 磁盘缓存),亦可通过 Headers标签查看具体缓存头以及通过响应状态码来判断缓存是否生效(200:从服务器获取,304:验证成功,使用缓存)。

由上面配置以及下图可知 /js/index.js 首次请求时,浏览器会从服务器获取资源并存入缓存中,缓存10s,到期后必须重新验证缓存,其传输大小为6k。第二次请求时,浏览器会直接使用缓存中的数据,并返回响应状态码为304(Not Modified),其传输大小仅为 0.3 k,极大减少了数据传输量,节约了带宽资源,看到了吧这边是利用缓存技术所带来的好处。

weiyigeek.top-使用开发者工具验证缓存图

若将上面location ~* \.(css|js)$块配置中的 expires 10s; 更改为 expires max;,则表示资源永不失效,浏览器将永久缓存该资源。

$ curl -s -o /dev/null -D - http://test.weiyigeek.top/js/index.js
HTTP/1.1 200 OK
Server: nginx/1.29.0
Date: Thu, 25 Dec 2025 01:24:34 GMT
Content-Type: application/javascript; charset=utf-8
Content-Length: 5638
Last-Modified: Wed, 24 Dec 2025 05:04:27 GMT
Connection: keep-alive
ETag: "694b745b-1606"
Expires: Thu, 31 Dec 2037 23:55:55 GMT   # 关键点,2037年12月31日后过期
Cache-Control: max-age=315360000         # 关键点,10年后过期
Cache-Control: public,  must-revalidate  # 关键点,公共缓存,过期后需要重新验证
Pragma: public
Accept-Ranges: bytes


步骤 04.作者也简单总结了 Nginx 对于静态资源可使用变量和条件语句实现更灵活的缓存策略

# 进阶配置
tee server.conf <<'EOF'
# 定义缓存文件类型映射
map $uri$expires_policy {
  default     1h;
# 永久缓存 - 带版本号的资源,例如:index.v1.1.min.js
  ~^/(css|js)/.+\.v[0-9]+(?:\\.[0-9]+)*\.(min\.)?(css|js)$ "max";
# 图片资源
  ~*\.(jpg|jpeg|png|gif|ico|webp|avif)$    1y;
# 字体文件
  ~*\.(woff2?|ttf|eot|svg)$                1y;
# CSS和JS(无版本号)- 适中缓存
  ~*\.(min\.)?(css|js)$                    7d;
# API接口
  ~^/api/   off;
}

server {
  listen 80;
# 虚拟主机服务器名称
  server_name server.weiyigeek.top;
  charset utf-8;
  default_type text/html;

# 启用 HTTP/2 支持
  http2 on;

# 启用 Etag 支持
  etag on;

# 日志文件
  access_log /var/log/nginx/server.log main;
  error_log /var/log/nginx/server.err.log debug;

# 根目录
  root /usr/local/nginx/html/WeiyiGeek;

# 主location块使用映射的 expires 值
  location / {
    index index.html;
    try_files $uri$uri/ /index.html;

    # 使用map定义的缓存策略
    expires $expires_policy;
    
    # 根据expires值设置Cache-Control
    if ($expires_policy = "max") {
      add_header Cache-Control "public, immutable, max-age=31536000";
    }
    if ($expires_policy = "off") {
      add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
    }
    
    # 通用缓存头(expires_policy 不为off或max时)
    if ($expires_policy !~ "(off|max)") {
      add_header Cache-Control "public";
    }
    
    # 安全头
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
  }

# 特殊处理:用户特定的内容不缓存
  location ^~ /api/ {
    expires -1;
    add_header Cache-Control "private, no-cache, no-store, must-revalidate, max-age=0";
    add_header Pragma "no-cache";
  }
}
EOF


步骤 05.再次重启 Nginx 服务,使用 curl 验证缓存配置是否生效。

# 验证1.验证 HTML 文件缓存配置是否生效,缓存一小时
$ curl -s -o /dev/null -D - http://server.weiyigeek.top/index.html

# 验证2.验证不带版本号以及带版本号的JS文件缓存配置是否生效,前者缓存7天,后则永久缓存
$ curl -s -o /dev/null -D - http://server.weiyigeek.top/js/index.js
$ curl -s -o /dev/null -D - http://server.weiyigeek.top/js/index.v1.min.js

# 验证3.验证图片资源缓存配置是否生效,图片资源缓存一年
$ curl -s -o /dev/null -D - http://server.weiyigeek.top/img/wechat-search.png

# 验证4.验证API目录中 gif 图片资源不缓存是否生效
$ curl -s -o /dev/null -D - http://test.weiyigeek.top/api/loading.gif
HTTP/1.1 200 OK
Server: nginx/1.29.0
Date: Thu, 25 Dec 2025 03:05:16 GMT
Content-Type: image/gif
Content-Length: 37072
Last-Modified: Wed, 24 Dec 2025 05:04:27 GMT
Connection: keep-alive
ETag: "694b745b-90d0"
Expires: Thu, 25 Dec 2025 03:05:15 GMT
Cache-Control: no-cache
Cache-Control: no-store, no-cache, must-revalidate, max-age=0 # 关键点,API目录的资源不缓存
Pragma: no-cache
Accept-Ranges: bytes

weiyigeek.top-使用curl验证静态资源缓存图

至此,作者带领大家完成了 Nginx 静态资源缓存的配置,并验证了其有效性。通过合理配置缓存策略,可以有效提升网站性能和用户体验。下一小节,将继续探讨 Nginx 后端(上游)缓存的相关指令、配置与实践。


阅读原文:原文链接


该文章在 2025/12/27 11:33:33 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved