Ubantu中使用Nginx反向代理静态资源缓存详细步骤过程记录

1,543 阅读5分钟

安装nginx

sudo apt install nginx

文件位置

  • /usr/sbin/nginx:主程序
  • /etc/nginx:存放配置文件
  • /usr/share/nginx:存放静态文件
  • /var/log/nginx:存放日志

启动命令

service nginx start # 启动nginx
service nginx reload # 重新加载nginx配置文件

另外两个命令

nginx -s reopen # 重启 Nginx
nginx -s stop # 停止 Nginx

明确一点,nginx做为静态资源服务器是不缓存的,只有在反向代理时才具体缓存功能

nginx.conf配置文件

##
# Proxy Setting
##
proxy_connect_timeout 10; #服务器连接的超时时间
proxy_read_timeout 180; # 连接成功后,等候后端服务器响应时间
proxy_send_timeout 5; #后端服务器数据回传时间
proxy_buffer_size 16k; #缓冲区的大小
proxy_buffers 4 32k; #每个连接设置缓冲区的数量为number,每块缓冲区的大小为size
proxy_busy_buffers_size 96k; #开启缓冲响应的功能以后,在没有读到全部响应的情况下,写缓冲到达一定大小时,nginx一定会向客户端发送响应,直到缓冲小于此值。
proxy_temp_file_write_size 96k; #设置nginx每次写数据到临时文件的size(大小)限制
proxy_temp_path /etc/nginx/temp; #proxy缓存临时文件的大小
proxy_cache_path /etc/nginx/cache levels=1:2 keys_zone=cache_one:100m inactive=1d max_size=10g; #设置缓存的路径和其他参数。被缓存的数据如果在inactive参数(当前为1天)指定的时间内未被访问,就会被从缓存中移除

Nginx只有在反向代理时才有缓存

/etc/nginx/temp 和 /etc/nginx/cache 文件需要提前创建并赋予写入权限

模拟假设资源在 /var/www/example.com,入口在/var/www/html

server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
#要缓存文件的后缀,可以在以下设置。
location ~ .*\.(gif|jpg|png|jpeg|css|js)(.*) {
    proxy_pass http://127.0.0.1:90; #nginx缓存里拿不到资源,向该地址转发请求,拿到新的资源,并进行缓存
    proxy_redirect off; #设置后端服务器“Location”响应头和“Refresh”响应头的替换文本
    proxy_set_header Host $host; #允许重新定义或者添加发往后端服务器的请求头
    proxy_cache cache_one; #指定用于页面缓存的共享内存,对应http层设置的keys_zone
#为不同的响应状态码设置不同的缓存时间
    proxy_cache_valid 200 302 24h;
    proxy_cache_valid 301 30d;
    proxy_cache_valid any 5m;
    expires 3m; # 显示给前端缓存时间
    add_header wall "hey!guys!give me a star.";
}
    location / {
    }
}

server {
listen 90;
listen [::]:90;
root /var/www/example.com;
location / {
    }
}

测试,二次刷新出现

image.png

服务器缓存文件

image.png

删除服务器缓存文件,可以判断是浏览器缓存

image.png 选择disable cancel强制刷新

HTML 禁止浏览器缓存

<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragm" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">

服务器只对html文件不缓存

缓存build打包js,css等文件带上时间戳(html引入更新及时)

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
#add_header X-Via $server_addr;
#要缓存文件的后缀,可以在以下设置。
location ~ .*\.(gif|jpg|png|jpeg|css|js)(.*) {
    #对不同的HTTP状态码设置不同的缓存时间
    proxy_pass http://127.0.0.1:90;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_cache cache_one;
    #以域名,URI,参数组合成web缓存的key值,nginx根据key值哈希
    proxy_cache_key $host$uri$is_args$args;
    # 为不同的响应状态码设置不同的缓存时间
    #proxy_cache_valid 200 10s;
    proxy_cache_valid any 100s; #缓存文件过期时间,未过期则304,过期则200重新访问缓存
    expires 30s; #浏览器端看到的max-age以及expires的值,前端根据这个决定是否请求服务器
    add_header Nginx-Cache "$upstream_cache_status";
}
location / {
    proxy_pass http://127.0.0.1:90;
}
}
server {
listen 90;
listen [::]:90;
root /var/www/not_save/;
index index.html;
location / {
# 配置页面不缓存html和htm结尾的文件
if ($request_filename ~* .*\.(?:htm|html)$) {
    add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}
    try_files $uri $uri/ /index.html =404;
}
}

当nginx设置了expires后,例如设置为:expires 10d;  那么用户在10天内请求的时候,都只会访问浏览器中的缓存,而不会去请求nginx。

Response Headers

cache-Control: max-age="过期所需时间/秒"; Expires:表示具体过期时间 image.png

在此期间若是只改变服务器静态资源是 不能 及时更新的

第一次访问

访问资源,直接下载

image.png 服务器静态资源缓存文件

image.png

第二次访问(Expires缓存未过期)

直接刷新页面 memory cache image.png

200 form memory cache 内存缓存

不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现from memory cache。

关闭浏览器再打开 disk cache

200 from disk cache 硬盘缓存

不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是from disk cache。

第二次访问(Expires缓存已过期)

等到expires过期后再刷新,确认服务器缓存过期则重新访问后台数据并返回200,未过期则304 image.png

*304 Not Modified

访问服务器,发现数据没有更新,服务器返回此状态码。然后从缓存中读取数据。

强制更新(Expires无论过期否,html引入静态资源变更)

前端webpack打包build,html的文件,html前端是禁止缓存的,服务器也没有缓存,所以会直接返回最新的html文件读取最新静态文件 image.png

add_header Nginx-Cache "$upstream_cache_status";

MISS 未命中,请求被传送到后端
HIT 缓存命中
EXPIRED 缓存已经过期请求被传送到后端
UPDATING 正在更新缓存,将使用旧的应答
STALE 后端将得到过期的应答

Expires

expires 30s; #缓存30秒
expires 30m; #缓存30分钟
expires 2h; #缓存2小时
expires 30d; #缓存30天

扩展知识 缓存具体类型

  • cache-control: max-age=xxxx,public 客户端和代理服务器都可以缓存该资源; 客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,如果用户做了刷新操作,就向服务器发起http请求
  • cache-control: max-age=xxxx,private 只让客户端可以缓存该资源;代理服务器不缓存 客户端在xxx秒内直接读取缓存,statu code:200
  • cache-control: max-age=xxxx,immutable 客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,即使用户做了刷新操作,也不向服务器发起http请求
  • cache-control: no-cache 跳过设置强缓存,但是不妨碍设置协商缓存;一般如果你做了强缓存,只有在强缓存失效了才走协商缓存的,设置了no-cache就不会走强缓存了,每次请求都回询问服务端。
  • cache-control: no-store 不缓存,这个会让客户端、服务器都不缓存,也就没有所谓的强缓存、协商缓存了。
  • max-age: 相对过期时间, 即以秒为单位的缓存时间. - private, 正数的max-age: 后退时候不会访问服务器. - no-cache, 正数的max-age: 后退时会访问服务器.
  • must-revalidate 缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。表示如果页面过期,则去服务器进行获取。
  • proxy-revalidate 与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。