Nginx服务器中强制使用缓存的配置及缓存优先级的讲解

nginx代理做好了,缓存也配置好了,但是发现css、js、jpg这些静态文件统统都cached成功。但是偏偏页面文件依旧到源服务器取。
1. nginx不缓存原因
默认情况下,nginx是否缓存是由nginx缓存服务器与源服务器共同决定的, 缓存服务器需要严格遵守源服务器响应的header来决定是否缓存以及缓存的时常。header主要有如下:

Cache-control:no-cache、no-store

如果出现这两值,nginx缓存服务器是绝对不会缓存的

Expires:1980-01-01

如果出现日期比当前时间早,也不会缓存。

2. 解决不缓存方案
2.1 方法一:
修改程序或者源服务器web程序响应的header
 
2.2 方法二:
nginx代理直接加上如下一句:

proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;

3.缓存优先级
3.1架构图
client端  <------------------>   nginx cache <------------------>源服务器
经过大量测试发现:nginx的过期顺序是有一个优先级的。下面首先说明各个影响缓存过期的因素:
(1)inactive:在proxy_cache_path配置项中进行配置,说明某个缓存在inactive指定的时间内如果不访问,将会从缓存中删除。
(2)源服务器php页面中生成的响应头中的Expires,生成语句为:
header("Expires: Fri, 07 Sep 2013 08:05:18 GMT");
(3)源服务器php页面生成的max-age,生成语句为:
header("Cache-Control: max-age=60");
(4)nginx的配置项 proxy_cache_valid:配置nginx cache中的缓存文件的缓存时间,如果配置项为:proxy_cache_valid 200 304 2m;说明对于状态为200和304的缓存文件的缓存时间是2分钟,两分钟之后再访问该缓存文件时,文件会过期,从而去源服务器重新取数据。
3.2其次对需要注意的一点:源服务器的expires和nginx cache的expires配置项的冲突进行说明,场景如下
(1)源服务器端有php文件ta1.php内容如下:

<?php
header("Expires: Fri, 07 Sep 2013 08:05:18 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: max-age=60");
echo "ta1";
?>

(2)在nginx cache服务器端的配置信息如下:

…….
proxy_cache_path /data0/proxy_cache_dir levels=1:2  keys_zone=cache_one:200m inactive=5s max_size=30g;
……..

location ~ .*\.(php|jsp|cgi)$
{
  proxy_read_timeout 10s;
  proxy_connect_timeout 10s;
  proxy_set_header Host $host;
  proxy_cache_use_stale updating;
  proxy_cache_key $host$uri$is_args$args;
  proxy_cache cache_one;
  #proxy_ignore_headers "Cache-Control";
  #proxy_hide_header "Cache-Control";
  #proxy_ignore_headers "Expires";
  #proxy_hide_header "Expires";
  proxy_hide_header "Set-Cookie";
  proxy_ignore_headers "Set-Cookie";
  #add_header Cache-Control max-age=60;
  add_header X-Cache '$upstream_cache_status from $server_addr';
  proxy_cache_valid 200 304 2m;
  #proxy_cache_valid any 0m;
  proxy_pass http://backend_server;
  expires 30s;
}
………….

从上面两项可以看出nginx cache 服务器中expires的配置是30s,该expires的值直接决定了在浏览器端看到的max-age以及expires的值。而源服务器断的代码中设置的响应头中的max-age为60,expires为Fri, 07 Sep 2013 08:05:18 GMT。这是源服务器的设置于nginx-cache的设置冲突了,那么着两个属性应该怎么设置呢?
这时client端的max-age与expires的值按照nginx cache中的expires配置项的设置,即:

Expires Fri, 07 Sep 2012 08:59:16 GMT
Cache-Controlmax-age=30

而nginx cache端的缓存的max-age与expire的值按照源服务器上的代码的设置。即:

Expires Fri, 07 Sep 2013 08:05:18 GMT
Cache-Controlmax-age=60

现在步入正题:
3.3经过大量测试发现:对缓存的过期与清除起作用的因素的优先级从高到低一次为:
inactive配置项、源服务器设置的Expires、源服务器设置的Max-Age、proxy_cache_valid配置项
下面通过几个实例对这几个优先级进行说明
实例1:
服务器端php代码:

<?php
header("Expires: Fri, 07 Sep 2012 08:03:18 GMT");//其实是3分钟之后
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: max-age=180");//2分钟
//header("Cache-Control: post-check=0, pre-check=0", false);
echo "ta1";
?>

nginx cache 配置项

inactive 4m//4分钟
proxy_cache_valid 1m//1分钟

现象:第一次访问页面ta1.php之后,各个时间的访问结果:

  • 1分钟之后 :HIT//这说明valid没有起作用
  • 2分钟之后 :HIT//这说明 源服务器设置的max-age没有起作用
  • 3分钟之后:MISS//这说明源服务器设置的Expires起作用了
  • 4分钟之后:MISS//这说明inactive起作用了

实例2:

服务器端php代码:

<?php
header("Expires: Fri, 07 Sep 2012 08:03:18 GMT");//3分钟之后
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: max-age=180");//2分钟
//header("Cache-Control: post-check=0, pre-check=0", false);
echo "ta1";
?>

nginx cache 配置项

inactive 10s//10秒钟
proxy_cache_valid 1m//1分钟

现象:第一次访问页面ta1.php之后,各个时间的访问结果:

  • 5秒后访问:HIT
  • 10秒后访问: MISS
  • 15秒后访问:HIT
  • 20秒后访问:MISS

通过实例1和实例2综合分析:如果inactive已经进行了设置,则缓存的过期时间以inactive设置的值为准

实例3:
服务器端php代码:

<?php
header("Expires: Fri, 07 Sep 1977 08:03:18 GMT");//直接过期
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: max-age=120");//2分钟
//header("Cache-Control: post-check=0, pre-check=0", false);
echo "ta1";
?>

nginx cache 配置项

inactive 4m//4分钟
proxy_cache_valid 1m//1分钟

现象:第一次访问页面ta1.php之后,各个时间的访问结果:
每隔一秒访问一次:MISS//这说明源服务器端设置的Expires屏蔽了nginx的valide和源服务器端设置的max-age的作用
实例4:
服务器端php代码:

<?php
header("Expires: Fri, 07 Sep 2012 08:03:18 GMT");//3分钟之后
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: max-age=120");//2分钟
//header("Cache-Control: post-check=0, pre-check=0", false);
echo "ta1";
?>

nginx cache 配置项

inactive 4m//4分钟

proxy_cache_valid 1m//1分钟

现象:第一次访问页面ta1.php之后,各个时间的访问结果:

  • 1分钟之后 :   HIT//这说明valid没有起作用,因为源服务器设置的Expires将valid的效果屏蔽了
  • 2分钟之后 :   HIT//这说明 源服务器设置的max-age没有起作用,因为源服务器设置的Expires将max-age屏蔽了
  • 3分钟之后:    MISS//这说明服务器端设置的expires起作用了

通过实例2和实例3的现象说明:如果inactive设置的比较大,在inactive到期之前,如果valid、服务器端设置的expires、服务器端设置的max-age都进行了设置,则以服务器端设置的expires为准。

实例5:
服务器端php代码:

<?php
header("Expires: Fri, 07 Sep 2012 08:03:18 GMT");//3分钟之后
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: max-age=120");//2分钟
//header("Cache-Control: post-check=0, pre-check=0", false);
echo "ta1";
?>

nginx cache 配置项

inactive 4m//4分钟
#下面两行用于消除服务器端配置的Expires响应头的影响
proxy_ignore_headers "Expires";
proxy_hide_header "Expires";
proxy_cache_valid 1m//1分钟

现象:第一次访问页面ta1.php之后,各个时间的访问结果:

  • 1分钟之后   HIT //这说明valid的作用已经被服务器端的max-age屏蔽
  • 2分钟之后   MISS//服务器端设置的max-age起作用

实例6:

服务器端php代码:

<?php
header("Expires: Fri, 07 Sep 2012 08:03:18 GMT");//3分钟之后
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: max-age=50");//50秒钟
//header("Cache-Control: post-check=0, pre-check=0", false);
echo "ta1";
?>

nginx cache 配置项

inactive 4m//4分钟
#下面两行用于消除服务器端配置的Expires响应头的影响
proxy_ignore_headers "Expires";
proxy_hide_header "Expires";
proxy_cache_valid 2m//2分钟

现象:第一次访问页面ta1.php之后,各个时间的访问结果:

  • 50秒钟之后 :   MISS//这说明服务器端配置的max-age起作用
  • 1分钟之后 :   HIT//
  • 100秒钟之后:   MISS//这说明服务器端设置的max-age起作用了

通过实例5和实例6的现象说明:如果inactive设置的比较大,而且在nginx配置文件中取消服务器端Expires对缓存的影响。在同时设置了proxy_cache_valid和服务器端设置了max-age响应头字段的情况下,以服务器端设置的max-age的值为标准进行缓存过期处理。

3.4综上所述:
(1)在同时设置了源服务器端Expires、源服务器端max-age和nginx cahe端的proxy_cache_valid的情况下,以源服务器端设置的Expires的值为标准进行缓存的过期处理
(2)若在nginx中配置了相关配置项,取消原服务器端Expires对缓存的影响,在同时设置了源服务器端Expires、源服务器端max-age和nginx cahe端的proxy_cache_valid的情况下,以源服务器端max-age的值为标准进行缓存的过期处理
(3)若同时取消源服务器端Expires和源服务器端max-age对缓存的影响,则以proxy_cache_valid设置的值为标准进行缓存的过期处理
(4)   Inactive的值不受上述三个因素的影响,即第一次请求页面之后,每经过inactvie指定的时间,都要强制进行相应的缓存清理。因此inactive的优先级最高。
(5)所以对缓存过期影响的优先级进行排序为:inactvie、源服务器端Expires、源服务器端max-age、proxy_cache_valid

时间: 2016-01-17

Nginx缓存Cache的配置方案以及相关内存占用问题解决

nginx缓存cache的5种方案 1.传统缓存之一(404) 这个办法是把nginx的404错误定向到后端,然后用proxy_store把后端返回的页面保存. 配置: location / { root /home/html/;#主目录 expires 1d;#网页的过期时间 error_page 404 =200 /fetch$request_uri;#404定向到/fetch目录下 } location /fetch/ {#404定向到这里 internal;#指明这个目录不能在外部直接访

Shell脚本批量清除Nginx缓存

前言*随着整个互联网的发展,产生了无数大大小小的网站,随之而来用户对网站UI和速度体验也在日益加强,对企业或者个人来说,赢得用户体验也就意味着赢得先机. 那今天我们在这里针对网站速度这方面来一起交流,提高网站速度对于运维工程师.程序员来说变得至关重要.运维工程师首先得在日常网站运维中发现影响网站速度的各种因素得逐个推动然后解决. 提高网站速度体验除了本身网站程序优化外,对于LinuxSA来说还有大量的工作要做,优化系统内核.调整WEB服务器的参数.优化数据库.增加网站架构缓存等等一系列的工作.

讲解Nginx服务器中设置本地浏览器缓存的简单方法

浏览器缓存(Browser Caching) 是为了加速浏览并节约网络资源,浏览器在用户磁盘上对最近请求过的文档进行存储. nginx可以通过 expires 指令来设置浏览器的Header 语法: expires [time|epoch|max|off] 默认值: expires off 作用域: http, server, location 使用本指令可以控制HTTP应答中的"Expires"和"Cache-Control"的头标,(起到控制页面缓存的作用).

Nginx配置srcache_nginx模块搭配Redis建立缓存系统

1. nginx模块 --add-module=../modules/ngx_devel_kit-0.2.18 --add-module=../modules/set-misc-nginx-module-0.22rc8 --add-module=../modules/srcache-nginx-module-0.22 --add-module=../modules/redis-nginx-module-0.3.6 --add-module=../modules/redis2-nginx-modu

Nginx服务器上搭建图片缓存服务的基本配置解析

最近准备用nginx搭建了一个图片服务器,看中的就是nginx超强的静态文件处理能力. 由于图片量比较大,和web服务器(也是nginx)分开运行,虽然web服务器调用图片没用问题,但毕竟是远程调用,肯定没有本地文件系统那么快,因此仍然有优化的空间. proxy_store 使用前的nginx配置 location ~* ^.+\.(js|ico|gif|jpg|jpeg|png|html|htm)$ { log_not_found off; access_log off; expires 7d

Nginx服务器作反向代理时的缓存配置要点解析

这里给出示例,并详解. http { [...] [...] proxy_cache_path /data/nginx/cache/one levels=1:2 keys_zone=one:10m max_size=10g; proxy_cache_key "$host$request_uri"; server { server_name www.jb51.net jb51.net; root /home/www.jb51.net/web; index index.php index.

Nginx上传文件全部缓存解决方案

下面通过文字说明给大家详解Nginx上传文件全部缓存解决方案. 因为应用服务器(Jetty)里面实现了上传时写了进度条.经过缓存.就没法读取到进度了.此外,在Nginx处缓存文件,也降低了传输效率. nginx采用1.5.6. 后端采用nodejs+formidable的方式接受上传文件,本问题的对应与采用什么样的后端没太大关系,这里只是交代一下. 问题: 在前端页面上将文件上传,nginx没有将每一块收到的文件数据块转发给后端,而是全部缓存了下来,全部收取完成后再一块一块的转发给后端,显而易见

Nginx服务器中浏览器本地缓存和虚拟机的相关设置

自动列出目录配置: 下载过开源软件的都知道,一个很简单的页面列出了所有版本的源码包,这就是开启了自动列出目录 如下配置,在虚拟主机location / {--}目录控制中配置自动列出目录: location / { autoindex on; } 浏览器本地缓存设置: 浏览器是为了加速浏览,浏览器在用户磁盘上对最近请求过的文件进行存储,当访问者再次请求这个页面, 浏览器可以从本地磁盘显示文件,以达到加速浏览的效果,节约了网络资源,提高了网络效率 关键字: expires 默认值: off 作用域

使用python删除nginx缓存文件示例(python文件操作)

调用时输入参数如:  www.jb51.net/表示删除www.jb51.net首页的缓存, www.jb51.net/test.php就表示删除/test.php的缓存 复制代码 代码如下: #coding=utf8import sys,osimport hashlibif len(sys.argv)<2:    print("你没有输入地址.")    sys.exit()path="/home/cache"#缓存目录md5v = hashlib.md5(

在varnish、squid、apache、nginx中选出一个更好的缓存服务器

一.varnish.squid.apache.nginx的区别 1.从这些功能上.varnish和squid是专业的cache服务,而apache,nginx这些都是第三方模块完成. 2.要做cache服务的话,我们肯定是要选择专业的cache服务,优先选择squid和varnish. varnish本身的技术上优势要高于squid,它采用了"Visual Page Cache"技术,在内存的利用上,Varnish比Squid具有优势,它避免了Squid频繁在内存.磁盘中交换文件,性能

如何在 Java 中实现一个 redis 缓存服务

缓存服务的意义 为什么要使用缓存?说到底是为了提高系统的运行速度.将用户频繁访问的内容存放在离用户最近,访问速度最快的地方,提高用户的响应速度.一个 web 应用的简单结构如下图. web 应用典型架构 在这个结构中,用户的请求通过用户层来到业务层,业务层在从数据层获取数据,返回给用户层.在用户量小,数据量不太大的情况下,这个系统运行得很顺畅.但是随着用户量越来越大,数据库中的数据越来越多,系统的用户响应速度就越来越慢.系统的瓶颈一般都在数据库访问上.这个时候可能会将上面的架构改成下面的来缓解数

Nginx中accept锁的机制与实现详解

前言 nginx采用多进程的模,当一个请求过来的时候,系统会对进程进行加锁操作,保证只有一个进程来接受请求. 本文基于Nginx 0.8.55源代码,并基于epoll机制分析 1. accept锁的实现 1.1 accpet锁是个什么东西 提到accept锁,就不得不提起惊群问题. 所谓惊群问题,就是指的像Nginx这种多进程的服务器,在fork后同时监听同一个端口时,如果有一个外部连接进来,会导致所有休眠的子进程被唤醒,而最终只有一个子进程能够成功处理accept事件,其他进程都会重新进入休眠

Nginx中虚拟主机与指定访问路径的设置方法讲解

添加多个虚拟主机 最近在ubuntu上捣腾nginx,安装成功了,就只有rewrite没有试验,因为服务器上有多个网站,还不敢在服务器上尝试,慢慢来.网上查了一些文章,下了一篇留下来做试验. nginx上虚拟主机的配置其实跟apache上的基本上类似. 需要注意的几点是: 第一.关于.htaccess配置,也就是为静态配置,在nginx上一般你要写在虚拟主机的配置文本中,但是我也有看到用包含文件解决这个问题的,即在虚拟主机配置脚本上include .htaccess文件,不过没有没有试过. 第二

在Nginx中使用X-Sendfile头提升PHP文件下载的性能(针对大文件下载)

很多时候用户需要从网站下载文件,如果文件是可以通过一个固定链接公开获取的,那么我们只需将文件存放到 webroot下的目录里就好.但大多数情况下,我们需要做权限控制,例如下载 PDF 账单,又例如下载网盘里的档案.这时,我们通常借助于脚本代码来实现,而这无疑会增加服务器的负担. 例如下面的代码: <?php // 用户身份认证,若验证失败跳转 authenticate(); // 获取需要下载的文件,若文件不存在跳转 $file = determine_file(); // 读取文件内容 $co

Nginx中共享session会话配置方法例子

Session一般都指时域.在计算机术语中,Session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间以及如果需要的话,可能还有一定的操作空间. Session一般都指时域.在计算机术语中,Session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间以及如果需要的话,可能还有一定的操作空间. 通常情况下能把session改成cookie,就能避开session的一些弊端,在从前看的一本J2EE的

Nginx中worker connections问题的解决方法

查看日志,有一个[warn]: 3660#0: 20000 worker_connections are more than open file resource limit: 1024 !! 原来安装好nginx之后,默认最大的并发数为1024,如果你的网站访问量过大,已经远远超过1024这个并发数,那你就要修改worker_connecions这个值 ,这个值越大,并发数也有就大.当然,你一定要按照你自己的实际情况而定,也不能设置太大,不能让你的CPU跑满100%. 所以,当你修改提高了配置

Nginx反向代理一个80端口下配置多个微信项目详解

Nginx反向代理一个80端口下配置多个微信项目详解 我们要接入微信公众号平台开发,需要填写服务器配置,然后依据接口文档才能实现业务逻辑.但是微信公众号接口只支持80接口(80端口).我们因业务需求需要在一个公众号域名下面,发布两个需要微信授权的项目,怎么办? 我们可以用nginx服务器做反向代理来解决这个问题.nginx服务器对外80端口,然后根据URL参数不同,对内访问不同的项目. nginx配置如下: 打开/usr/local/nginx/conf/nginx.conf worker_pr

在Nginx中拦截特定用户代理的教程

现代互联网滋生了大量各种各样的恶意机器人和网络爬虫,比如像恶意软件机器人.垃圾邮件程序或内容刮刀,这些恶意工具一直偷偷摸摸地扫描你的网站,干些诸如检测潜在网站漏洞.收获电子邮件地址,或者只是从你的网站偷取内容.大多数机器人能够通过它们的"用户代理"签名字符串来识别. 作为第一道防线,你可以尝试通过将这些机器人的用户代理字符串添加入robots.txt文件来阻止这些恶意软件机器人访问你的网站.但是,很不幸的是,该操作只针对那些"行为良好"的机器人,这些机器人被设计遵循

详解Nginx中的geo模块与利用其配置负载均衡的示例

geo指令使用ngx_http_geo_module模块提供的.默认情况下,nginx有加载这个模块,除非人为的 --without-http_geo_module. ngx_http_geo_module模块可以用来创建变量,其值依赖于客户端IP地址. geo指令 语法: geo [$address] $variable { ... } 默认值: - 配置段: http 定义从指定的变量获取客户端的IP地址.默认情况下,nginx从$remote_addr变量取得客户端IP地址,但也可以从其他