Skip to content

Latest commit

 

History

History
218 lines (201 loc) · 7.99 KB

14.md

File metadata and controls

218 lines (201 loc) · 7.99 KB

Nginx配置代理缓存

  • 使用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的配置,此处不再赘述

程序示例

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服务器性能的常见方法

  • 写一些脚本让其缓存使用内存数据库,这样搜索性能会更高
    • 默认情况下,nginx缓存写在磁盘上的,读写磁盘效率较低
  • 设置cache key
  • 其他配置...