Nginx代理缓存静态资源

问题描述

有两台服务器,一台是外网的网关服务器,一台是内网的资源服务器,但是两台服务器距离很远(跨省),页面中依赖大量插件资源,加载耗时久,本章重点讲解Nginx代理缓存静态资源。

解决思路

  • CDN
  • 开启gzip压缩
  • 图片格式优化,找到大图片
  • 外网服务器进行静态资源缓存

proxy_cache工作原理

Nginx 的 proxy_cache 模块允许 Nginx 作为反向代理服务器时缓存后端服务器的响应。以下是 proxy_cache 模块的工作原理:

  1. 请求到达:客户端向 Nginx 发送请求。
  2. 缓存查找:Nginx 首先检查请求是否命中缓存。这是通过查找共享内存中的缓存键(由 proxy_cache_key 定义)来完成的。
  3. 缓存命中:如果请求命中缓存,Nginx 直接从缓存中读取响应并返回给客户端。
  4. 缓存未命中:如果请求未命中缓存,Nginx 将请求转发到后端服务器。
  5. 后端响应:后端服务器处理请求并返回响应给 Nginx。
  6. 缓存存储:Nginx 将后端服务器的响应存储在本地文件系统中,同时在共享内存中更新缓存键和元数据。
  7. 返回响应:Nginx 将后端服务器的响应返回给客户端,并根据 proxy_cache_valid 指令设置的规则决定缓存时间。

配置

sh 复制代码
# 设置日志格式,$upstream_cache_status代表是否命中缓存
# $upstream_cache_status的返回值有7个:
# HIT表示缓存命中
# MISS表示未命中,请求被传送到后端
# EXPIRED表示缓存已经过期,请求被传送到后端
# UPDATING表示正在更新缓存,将使用旧的应答
# STALE表示无法从后端服务器更新缓存时,返回了旧的缓存内容
# BYPASS表示缓存被绕过了
# REVALIDATED表示启用proxy_cache_revalidate指令后,当缓存内容过期时,Nginx通过一次If-Modified-Since的请求头去验证缓存内容是否过期,此时会返回该状态
log_format  main  '$remote_addr - $remote_user [$request_time] [$time_local] "$request" '
                      '$upstream_cache_status '                      
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
# 打开日志格式化功能,如果这里不打开的话,上面的格式化不生效
access_log  logs/access.log  main;

# 设置缓存区信息
# levels:指定该缓存空间对应的目录,最多可以设置3层,每层取值为1|2;例如:levels=1:2   缓存空间有两层目录,第一次是1个字母,第二次是2个字母
proxy_cache_path /app/nginx/js_cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;

# --------------以下为server中的配置---------------
location / {
	proxy_pass http://ip:端口;
}
# 启用缓存
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|ico|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma|css|js)$ {
	proxy_pass http://ip:端口;
	proxy_cache my_cache;
	# proxy_cache_valid设置不同响应码的缓存过期时间
	# HTTP 206 Partial Content(部分内容)状态码表示服务器成功处理了客户端‌请求资源部分内容‌的GET请求,主要应用于支持范围请求(Range Request)的场景,比如文件断点下载
   	proxy_cache_valid 200 304 206 60m; # 缓存200, 304, 206响应3600秒(1小时)
   	proxy_cache_key $uri; # 缓存键的生成方式
    # add_header X-Cache '$upstream_cache_status from $host'; # 在请求的http响应头中返回,判断是否命中缓存
}

proxy_cache_path与proxy_cache_valid中超时时间同时设置,生效控制问题

inactive时间到了,数据删除。proxy_cache_valid时间到了不会被删除,但是会认为失效,再次请求时会重新下载。有请求,inactive就刷新计时,valid不变。没请求,inactive和valid都不变。

分析各种情况:

  1. inactive设置1m,valid设置1h

    首先,请求进来,cache出现,两个时间开始倒计时。

    情况一:不断请求这个cache,inactive不断刷新1m倒计时,直到到达1h,valid过期。这时你去请求了一次,nginx重新去读取服务器数据,刷新valid倒计时。期间数据一直在缓存里。不请求,就再过1m删掉。

    情况二:两次请求间隔超过了1min,inactive生效,删除了这个cache数据,没了。你再请求,相当于重新去服务器拿了一次数据,inactive和valid倒计时都会重新刷新,不请求,cache里就没有这份数据了

  2. inactive设置1m,valid设置1m

    首先,请求进来,cache出现,两个时间开始倒计时。

    情况一:1m内不请求,最后inactive生效删掉。不请求就没缓存了,请求了一次,重新从服务器读取一份,两个计时刷新。

    情况二:1m内请求了一次,inactive时间刷新,但是valid还在计时,所以1m到了后,缓存过期了。你再请求就重新从服务器读取一份,刷新计时。不请求,就等待1m,由inactive生效删除了缓存

  3. inactive设置1h,valid设置了1m

    首先,请求进来,cache出现,两个时间开始倒计时。

    过了1m,缓存过期,数据在没删掉。不请求,直到1h到,inactive删掉缓存。请求了一次,重新从服务器读取,刷新两个计时。

所以,通常inactive应该需要设置的比valid中时间长,inactive和valid是配合使用,不是谁时间短覆盖谁的关系。

缓存清理

清除缓存,直接删除缓存文件夹,下次请求的时候会重新生成

外网缓存失败,内网不允许缓存

在生产环境出现过一个问题,在外网服务器nginx配置了缓存信息,日志配置生效,缓存目录也生成,但是始终没有生成缓存文件,最后排查发现,在内网的nginx配置了如下禁止缓存的信息,应该将此段内容从内网服务器移到外网上或者使用proxy_ignore_headers

复制代码
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
add_header Pragma no-cache;
add_header Expires 0;

private:专用于个人的缓存,中间代理、CDN 等不能缓存此响应

public:响应可以被中间代理、CDN 等缓存

参考

nginx proxy_cache缓存详解(强烈推荐)
nginx配置proxy_cache_path之inactive和proxy_cache_valid对比
Nginx 缓存系统 proxy_cache详解

相关推荐
群联云防护小杜3 小时前
服务器异常磁盘写排查手册 · 已删除文件句柄篇
运维·服务器·nginx·开源·lua
川石课堂软件测试14 小时前
Oracle 数据库:视图与索引
数据库·网络协议·nginx·http·oracle·grafana·prometheus
小妖66614 小时前
mac 安装 nginx
运维·nginx·macos
Whitess00714 小时前
Websocket链接如何配置nginx转发规则?
websocket·网络协议·nginx
if时光重来1 天前
springboot项目使用websocket功能,使用了nginx反向代理后连接失败问题解决
spring boot·websocket·nginx
xiaozhenghahaha1 天前
Web相关知识(草稿)
运维·nginx
柯南二号1 天前
【后端】Docker 常用命令详解
服务器·nginx·docker·容器
工会代表1 天前
nginx配置,将前端项目配置到子路径下踩过的坑。
前端·nginx
云霄IT1 天前
CentOS7安装Nginx服务——为你的网站配置https协议和自定义服务端口
服务器·nginx·https
XMYX-01 天前
Tengine/Nginx 安装以及模块查看与扩展
运维·nginx