nginx缓存与http缓存

简介

http缓存分为两类:http客户端(浏览器)的缓存和代理服务器(如nginx)缓存。
浏览器的缓存可以减少浏览器和服务器之间的数据交互,而代理服务器的缓存是减少代理服务器和后端应用服务器的交互。

浏览器缓存

缓存命中类型:

浏览器可以缓存服务器发来的页面,如果短时间重复访问同一个页面,缓存的数据就在浏览器进程的内存中
;如果间隔时间长一点,缓存的数据存放在浏览器所在电脑的磁盘上。
在谷歌浏览器F12 -> network可以看到每个文件对应的size,如果缓存命中,可以看到size为memory cached和disk cached。

在获取页面后立即刷新就容易看到memory cache

实现原理

实现缓存只需要解决一个问题:浏览器如何判断页面是否需要缓存和缓存页面是否有效。可以分为两种解决方案:

  • 服务器在http响应头部中添加页面有效时长的值,浏览器自动缓存这类页面到本地,然后浏览器在请求页面的时候先检查有没有缓存,如果有缓存就判断是否在有效时间内。这种方式被称为强缓存,速度快,但是存在如果服务器更新了页面,不能立即告诉浏览器,必需等待浏览器的缓存数据失效。http1.0的响应头的Expires实现该功能, http1.1的Cache-Control的max-age也可以实现该功能。
  • 服务器在http响应头部中添加一个响应内容的hash码(etag),浏览器自动缓存这类页面到本地,然后浏览器在请求页面的时候先检查有没有缓存,如果有缓存就给服务器发送缓存页面的hash码,服务器通过hash码判断页面是否有更新,如果更新了就给浏览器发送新的页面(响应码200);也可以给浏览器发送一个页面未更改的响应(响应码304),从而减少数据传输。这种方式称为协商缓存,比通过设置有效时间的方式慢,但是服务器可以灵活控制浏览器是否使用缓存数据。实现方式:响应头部Last-Modified和和请求头部If-Modified-Since,或响应头部Etag和请求头部If-None-Match

cache-control

Cache-Control是http1.1出现的,用来控制缓存行为,比Expires优先级高,功能丰富,可以包含的值有:

  • public: 表明响应可以被任何对象(浏览器,代理服务器)缓存
  • private: 表明响应应该只能被客户端缓存
  • no-cache: 跳过强缓存,直接进入协商缓存阶段
  • no-store: 表示当前请求资源禁用缓存
  • max-age=xx :表示缓存最大周期,单位为秒
  • s-maxage=xx: 覆盖max-age或者Expires头。如果s-maxage未过期,则向代理服务器请求其缓存内容

nginx缓存

如果希望nginx可以缓存页面,响应的http头部Cache-Control不能设置private,no-cahce,no-store任意一个值,如果响应中没有Cache-Control字段,可以通过nginx配置文件中配置proxy_cache_valid进行缓存。
代理服务器缓存配置

[root@testdsq conf.d]# cat c.conf
proxy_cache_path /usr/local/nginx/cache levels=1:2 keys_zone=dsqtest:10m inactive=60s max_size=10G;
server {
        listen 2002;
        location / {
                proxy_pass http://192.168.1.3:2002/;
                proxy_cache dsqtest;
											#方便查看缓存命中情况
                add_header cache $upstream_cache_status;
        }

}

  • /usr/local/nginx/cache是缓存文件路径
  • levels是缓存文件存放路径结构,这里把文件放到2层目录之下。nginx生成文件的md5值,假如是dae503fea0c6647410b8b62826090023aed,然后文件会被放到/usr/local/nginx/cache/d/ae/503fea0c6647410b8b62826090023aed下面
  • kesy_zone=dsqtest:10m dsqtest是对缓存的命名,10m是内存存放文件名的缓存大小
  • inactive=60s 指定60s内没有被访问到的缓存文件会被清理掉,这里为了测试,所以设置的比较小

后端服务器192.168.1.3 nginx代理配置

[root@fileserver-dsq conf.d]# cat x.conf
server {
    listen 2002;
    server_name  _;
    location / {
				#需要设置有效时间,否则代理不会缓存
                expires 180s;
                root /usr/local/nginx/html;
    }
}

curl访问测试

[root@testdsq conf.d]# curl -I http://192.168.1.3:2002/
HTTP/1.1 200 OK
Server: hnbweb
Date: Thu, 18 Apr 2024 02:20:49 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 624
Connection: keep-alive
Last-Modified: Wed, 17 Apr 2024 10:24:36 GMT
ETag: "661fa364-270"
Expires: Thu, 18 Apr 2024 02:23:49 GMT
Cache-Control: max-age=180
cache: MISS
Accept-Ranges: bytes

[root@testdsq conf.d]# curl -I http://192.168.1.3:2002/
HTTP/1.1 200 OK
Server: hnbweb
Date: Thu, 18 Apr 2024 02:20:50 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 624
Connection: keep-alive
Last-Modified: Wed, 17 Apr 2024 10:24:36 GMT
ETag: "661fa364-270"
Expires: Thu, 18 Apr 2024 02:23:49 GMT
Cache-Control: max-age=180
cache: HIT
Accept-Ranges: bytes
  • 可以看到第一次cache是MISS第二次是HIT,60s后访问就会又是MISS,说明代理清除了缓存文件;
  • 可以看到代理服务器的/usr/local/nginx/cache下生成了缓存文件。
    浏览器访问测试
    第一次

第二次

  • 第二次浏览器发送的请求里面有If-None-Match和If-Modified-Since来校验缓存是否失效。

nginx缓存配置

  • proxy_cache_path 配置缓存文件存放路径
  • proxy_cache 使用proxy_cache_path配置的缓存
  • proxy_cache_valid 配置不同状态码的响应的缓存存放时长,当响应中不存在etag或max-age的时候,nginx默认是不会缓存的,这种时候如果想要使用nginx代理进行缓存,那就可以使用proxy_cache_valid配置。http的头部的缓存控制字段的优先级比proxy_cache_valid高
  • proxy_cache_revalidate 配置当缓存过期的时候是否使用“If-Modified-Since”或者“If-None-Match”校验缓存数据
  • proxy_cache_key 设置如何区分页面的唯一性
posted @ 2024-04-19 11:27  董少奇  阅读(40)  评论(0)    收藏  举报