- 使用
proxy_cache_path
来配置一个cache, 示例proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m
- 这里的 cache 是缓存文件的路径
- windows使用相对路径,为nginx安装目录下
- mac可以设置自己的路径,如/var/cache/你的目录
- levels 表示是否要创建多级文件夹
- 因为cache目录声明之后会用于很多代理服务器
- 默认所有代理会存在于一个目录中导致查找速度变慢
- 分级文件会优化速度
- keys_zone 表示代理缓存指定名称
- 查找缓存时用的名称和缓存大小声明
- 例子里是缓存大小为10M, 之后就可以直接使用了,如
server { listen 80; server_name test.com; location / { proxy_cache my_cache proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; } }
- 这时候代理已经配置成功了,然后我们重启nginx后进行使用
- 特别注意,针对我们的server_name,本机也要进行一些host的配置,此处不再赘述
- 这里的 cache 是缓存文件的路径
1 ) 代理缓存示例
- test.html
<div>response: <span id='data'></span></div> <script> fetch('/data').then(function(res) { return res.text(); }).then(function(text) { document.getElementById('data').innerText = text; }); </script>
- server.js
const http = require('http'); const fs = require('fs'); // 延迟函数 const delay = (s) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, s * 1000); }); } http.createServer((req, res) => { console.log('req come: ', req.url); const html = fs.readFileSync('test.html', 'utf8'); if(res.url === '/') { res.writeHead(200, { 'Content-Type': 'text/html', }); res.end(html); } // 模拟数据请求 if(res.url === '/data') { // 延迟2s返回数据 delay(2).then(() => { res.end('success'); }); } }).listen(8000, () => { console.log('server is running on port 8000'); });
- 启动服务,观察页面,多刷新几次,可以看到都是2s之后才出现的数据
- 现在我们来修改一下,加一个缓存
- server.js
// 模拟数据请求 if(res.url === '/data') { res.writeHead(200, { 'Cache-Control': 'max-age=20', }); // 延迟2s返回数据 delay(2).then(() => { res.end('success'); }); }
- 注意,重启程序之后,刷新浏览器之前要保持Disable cache不被勾选
- 刷新浏览器访问,第一次是2s之后,第二次就会非常快,而且显示from disk cache
- 可见,这里设置了max-age,浏览器是有缓存的,但是这并没有体现出来nginx的代理缓存的作用
- 为了能体现代理缓存发生作用,可以再刷新一次原浏览器,使用新的浏览器来访问
- 这时候,新浏览器迅速就能拿到返回结果,这就是代理缓存的作用
- 代理缓存是在代理服务器那一层设置,每一个新请求都会经过代理服务器
- 只要有一个客户端请求了,代理服务器就会缓存一次数据
- 这时候其他客户端再次使用就可以直接使用代理缓存
- 在这里,我们的Nginx服务器就是代理服务器
2 ) 对比代理缓存设置的HTTP头与其他头的关系
2.1 ) max-age=2与s-maxage=20的结合使用
- server.js 修改程序
// 模拟数据请求 if(res.url === '/data') { // 修改部分 res.writeHead(200, { 'Cache-Control': 'max-age=2, s-maxage=20', }); // ... }
- 重启程序,刷新浏览器(同样注意保持Disable cache不被勾选)
- 发现第一次刷新比较慢
- 并迅速刷新第二次(2s之内)很快并显示from disk cache
- 刷新第三次(距离第一次2s之后,20s之内)仍旧很快, 但并不显示from disk cache
- 可见,第二次属于max-age=2的作用,第三次属于s-maxage=20的作用
- 同时设置
'max-age=2, s-maxage=20
可知,浏览器使用max-age,代理服务器使用s-maxage
2.2 ) private头的作用
- 我们修改程序,再加一个private头
- server.js 修改程序
// 模拟数据请求 if(res.url === '/data') { // 修改部分 res.writeHead(200, { 'Cache-Control': 'max-age=5, s-maxage=20, private', }); // ... }
- 重启程序,刷新浏览器(同样注意保持Disable cache不被勾选)
- 发现第一次刷新比较慢
- 并迅速刷新第二次(5s之内)很快并显示from disk cache
- 刷新第三次(距离第一次5s之后,20s之内)发现比较慢
- 这是因为s-maxage=20的设置并没有生效, 没有使用到代理缓存, 原因是设置了private
- private表示只有浏览器才能缓存数据,代理服务器是不能缓存的
2.3 ) no-store头的作用
- 我们修改程序,把private换成no-store
- server.js 修改程序
// 模拟数据请求 if(res.url === '/data') { // 修改部分 res.writeHead(200, { 'Cache-Control': 'max-age=5, s-maxage=20, no-store', }); // ... }
- 重启程序,刷新浏览器(同样注意保持Disable cache不被勾选)
- 怎么刷新操作,不管是浏览器还是代理服务器它都不缓存任何数据,都是很慢
2.4 ) Vary头的用处
- 关于Vary的HTTP头的使用, Vary的作用是只有指定的信息相同,才会使用同一份缓存
- test.html
<div>response: <span id='data'></span></div> <button id='btn'>Click Here</button> <script> var index = 0; var dataDom = document.getElementById('btn'); dataDom.innerText = ''; function req() { fetch('/data', { headers: { 'X-Test-Cache': index++ } }).then(function(res) { return res.text(); }).then(function(text) { document.getElementById('data').innerText = text; }); } dataDom.addEventListener('click', req); </script>
- server.js 修改程序
// 模拟数据请求 if(res.url === '/data') { // 修改部分 res.writeHead(200, { 'Cache-Control': 's-maxage=200', 'Vary': 'X-Test-Cache' }); // ... }
- 重启程序,刷新浏览器(同样注意保持Disable cache不被勾选)
- 我们现在点击Click Here按钮两次
- 发现第一次点击响应很慢,请求头信息中
X-Test-Cache:0
- 第二次点击响应仍很慢,请求头信息中
X-Test-Cache:1
- 发现第一次点击响应很慢,请求头信息中
- 好,现在我们刷新浏览器(同样注意保持Disable cache不被勾选)
- 我们现在点击Click Here按钮四次
- 第一次点击响应很快,请求头信息中
X-Test-Cache:0
,因为之前代理服务器缓存过了 - 第二次点击响应仍很快,请求头信息中
X-Test-Cache:1
,因为之前代理服务器缓存过了 - 第三次点击响应很慢,请求头信息中
X-Test-Cache:2
,因为之前代理服务器没有进行缓存 - 第四次点击响应很慢,请求头信息中
X-Test-Cache:3
,因为之前代理服务器没有进行缓存
- 第一次点击响应很快,请求头信息中
- 这个试验表明,通过Vary头信息的验证,对于同一个请求url, 只有完全相同的Vary头信息才会使用缓存
- 这个使用场景很常见,比如不同的客户端(移动端和PC端)的不同,需要的内容不同,使用不同的缓存内容
- 写一些脚本让其缓存使用内存数据库,这样搜索性能会更高
- 默认情况下,nginx缓存写在磁盘上的,读写磁盘效率较低
- 设置cache key
- 其他配置...