一、nginx代理缓存

  客户端第一次向服务器请求数据,此时nginx没有缓存,nginx会向服务器请求数据,服务器响应请求,nginx会将服务器响应的数据缓存起来后再向客户端响应,当客户端第二次发送请求时,此时nginx有缓存就不会再向服务器发送请求,而是直接将之前的缓存返回给客户端。

  这样可以减轻服务器端的压力。

 

二、代理缓存配置项

 1.proxy_cache_path(缓存路径配置)

  该指令用于设置存储缓存数据的路径以及缓存索引相关的内容

Syntax:    proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] 
      [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time]
      [use_temp_path=on|off] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default: —
Context: http

  path:设置缓存数据存放的根路径,该路径应该是预先存在与磁盘上的。

  levels=levels:设置在相对于path指定目录的第几级hash目录中缓存数据。levels=1,表示一级hash目录;levels=1:2,表示两级,依次类推。目录的名称是基于请求URL通过哈希算法获取到的。

  keys_zone=name:size:Nginx服务器的缓存索引重建进程在内存中为缓存数据建立索引,这一对变量用来设置存放缓存索引的内存区域的名称和大小。

  inactive=time:设置强制更新缓存数据的时间,当硬盘上的缓存数据在设定的时间内没有被访问时,Nginx服务器就强制从硬盘上将其删除,下次客户端访问该数据时重新缓存。该指令默认设置为10s。

  max_size=size:设置硬盘中缓存数据的大小限制。我们知道,硬盘中的缓存源数据由Nginx服务器的缓存管理进程进行管理,当缓存的大小超过该变量的设置时,缓存管理进程将根据最近最少被访问的策略删除缓存。

  manager_files=number:设置缓存索引重建进程每次加载的数据元素的数量上限。在重建缓存索引的过程中,进程通过一系列的递归遍历读取硬盘上的缓存数据目录及缓存数据文件,对每个数据文件中的缓存数据在内存中建立对应的索引,我们称每建立一个索引为加载一个数据元素。进程在每次遍历过程中可以同时加载多个数据元素,该值限制了每次遍历中同时加载的数据元素的数量。默认设置为10s。

  manager_sleep=time:设置缓存索引重建进程在一次遍历结束、下次遍历开始之间的暂停时长。默认设置为50ms。

  manager_threshold=time:设置遍历一次磁盘缓存源数据的时间上限。默认设置为200ms。

  该指令设置比较复杂,一般需要设置前面三个指令的情形比较多,后面的几个变量与Nginx服务器缓存索引重建进程及管理进程的性能相关,一般情况下保持默认设置就可以了。该指令只能放在http块中。

 2.proxy_cache_valid(缓存过期周期)

  该指令可以针对不同的HTTP响应状态设置不同的缓存时间。

Syntax:    proxy_cache_valid [code ...] time;
Default: —
Context: http, server, location

//示例
proxy_cache_valid 200 302 10m (200和302状态码缓存10分钟)
proxy_cache_valid 404 1m (404状态码缓存1分钟)

3.proxy_cache_key(缓存的维度)

  该指令用于设置Nginx服务器在内存中为缓存数据建立索引时使用的关键字。

Syntax:    proxy_cache_key string;
Default: proxy_cache_key $scheme$proxy_host$request_uri;
Context: http, server, location

//示例
proxy_cache_key "$host$request_uri$cookie_user"(缓存域名、请求url、cookie信息)

4.proxy_no_cache(设置不缓存)

  该指令用于配置在什么情况下不使用cache功能。

Syntax:    proxy_no_cache string ...;
Default: —
Context: http, server, location
#string可以是一个或者多个变量。当string的值不为空或者不为“0”时,不启用cache功能。

三、设置缓存

#设置代理的负载
upstream cache {
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;  
}

#proxy_cache_path 设置路径
#levels 设置目录级别,一般设置为1:2,两级目录
#keys_zone=code_cache:10m 开辟空间的名字定义为code_cache大小10M
#max_size=10g 缓存最大10G,超出10G,清理访问量少的缓存
#inactive=60m 表示60分钟内如果没有被访问过就清掉
#use_temp_path 表示生成临时文件缓存,为了防止冲突,所以关闭
proxy_cache_path /opt/app/cache levels=1:2 keys_zone=code_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    listen       80;
    server_name  localhost;

    location / {
      proxy_pass http://cache; #代理到cache负载 
      
      proxy_cache code_cache;  #开启缓存 off关闭缓存
      
      proxy_cache_valid 200 304 12h;  #表示对200 304头信息12小时过期
      
      proxy_cache_valid any 10m; #表示除200 304头信息10钟过期
      
      add_header Nginx-Cache "$upstream_cache_status";  
      #添加一个头信息,告知客户端是否命中缓存
      #如果没有命中,在Response Header中有字段Nginx-Cache:Miss
      #如果命中缓存,字段:Nginx-Cache:HIT

      proxy_cache_key $host$uri$is_args$args;  #设置缓存的key

      proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
      #当返回的头信息中有500,502,503,504就跳过当前访问下一台服务器
    }
    
}

四、设置指定代理不缓存

server{
    #......其他配置
    #表明用户访问login和search两个url页面的时候,变量$nocache 设置为1
        if ($request_uri ~ ^/(login|search)){
            set $nocache 1;
        }
        location / {
         # ....
         # 当变量$nocache 为1,不缓存。
         proxy_no_cache $nocache $arg_nocache $arg_comment;
         proxy_cache_key $uri$is_args$args;
    }
}

五、location规则

1.优先级规则

    locaiton有四种类型的匹配规则:

  【=】模式: location = path,此种模式优先级最高(但要全路径匹配);

  【^~】模式:location ^~ path,使用前缀匹配,此种模式优先级第二,不支持正则表达式。如果有多个location匹配的话,则使用表达式最长的那个;

  【~ or ~*】模式:location ~ path,正则模式,优先级第三,【~】正则匹配区分大小写,【~*】正则匹配不区分大小写;

  【path】模式: location path,中间什么都不加,直接跟路径表达式;

2.路径替换规则

  配置proxy_pass时,可以实现URL路径的部分替换。

  proxy_pass的目标地址,默认不带/,表示只代理域名(把请求的path拼接到proxy_pass目标域名之后作为代理的URL)

  如果在目标地址后增加/,则表示把path中location匹配成功的部分剪切掉之后再拼接到proxy_pass目标地址。

# 比如请求 /a/b.html
# http://server/a/b.html  (把/a/b.html拼接到http://server之后)
location /a {
    proxy_pass http://server;
}
# http://server/b.html (把/a/b.html的/a去掉之后,拼接到http://server/之后)
location /a {
    proxy_pass http://server/;
}

  注意:对于location为正则表达式的匹配,proxy_pass的目标地址不能带/。