前言
为了提升网站的整体性能,我们一般会采用缓存,从宏观层面来说,会采用浏览器缓存和后端焕春,Nginx处于Web网站的服务最外层,而且支持浏览器缓存配置和后端数据缓存,用它来做部分部分数据缓存,效率更高。
Web缓存是可以自动保存常见的文档副本打HTTP设备。当Web请求抵达缓存时,如果本地有"已缓存的"副本,就可以从本地设备而不是服务器中提取这个文档。
OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。
OpenResty的中文官方学习地址 http://openresty.org/cn/
安装依赖库
yum install wget libtermcap-devel ncurses-devel libevent-devel readline-devel pcre-devel gcc openssl openssl-devel per
下载安装包
wget https://openresty.org/download/openresty-1.11.2.5.tar.gz
解压安装
tar -xf openresty-1.11.2.5.tar.gz
cd openresty-1.11.2.5
./configure --prefix=/usr/local/openresty --with-luajit --without-http_redis2_module --with-http_stub_status_module --with-http_v2_module --with-http_gzip_static_module --with-http_sub_module --add-module=/usr/local/server/ngx_cache_purge-2.3/
make && make install
这里有一个缓存清理模块ngx_cache_purage-2.3
可使用wget https://gitee.com/cxsunfeng/cache/raw/9956486379125cfbfc57e794a7a374a11c9e6c68/nginx-cache/ngx_cache_purge-2.3.tar.gz
下载
安装完成后,在 /usr/local/openrestry/nginx 目录下是安装好的nginx。
客户端侧缓存一般指的是浏览器缓存、app缓存等等,目的就是加速各种静态资源的访问,降低服务器压力。
我们通过配置Nginx设置网页缓存信息,从而降低用户对服务器频繁访问造成的巨大压力。我们先配置一个案例,再基于案例去讲解Nginx缓存
nginx 提供了 expires 、 etag 、 if-modified-since 指令来进行浏览器缓存控制。我们使用 expires 来配置Nginx对网页的缓存。
语法: expires [modified] time;
默认值: expires off;
上下文: http, server, location, if in location
1)上传html
将1.html上传到服务器的 /usr/local/server/html 目录下
1.html 内容为:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>1111111title>
head>
<body>
测试数据。。。。。。。。。。。。。。
body>
html>
2)配置nginx
修改 /usr/local/openrestry/nginx/conf/nginx.conf 文件,配置如下:
server {
listen 80;
server_name localhost;
location / {
#静态文件路径
root /usr/local/server/html;
#缓存10秒
expires 10s;
}
}
过期时间配置说明
expires 30s; #30秒
expires 30m; #30分钟
expires 2h; #2个小时
expires 30d; #30天
第一次访问 192.168.139.187/1.html
第二次访问 192.168.139.187/1.html
HTTP 中最基本的缓存机制,涉及到的 HTTP 头字段,包括 Cache-Control, Last-Modified,
If-ModifiedSince, Etag,If-None-Match 等。
Last-Modified/If-Modified-Since
Etag是服务端的一个资源的标识,在 HTTP 响应头中将其传送到客户端。所谓的服务端资源可以是一个Web页面,
也可以是JSON或XML等。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端。比如,
浏览器第一次请求一个资源的时候,服务端给予返回,并且返回了ETag: "50b1c1d4f775c61:df3" 这样的字样给
浏览器,当浏览器再次请求这个资源的时候,浏览器会将If-None-Match: W/"50b1c1d4f775c61:df3" 传输给服
务端,服务端拿到该ETAG,对比资源是否发生变化,如果资源未发生改变,则返回304HTTP状态码,不返回具体的
资源。
Last-Modified :标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since :当资源过期时(使用Cache-Control标识的max-age),发现资源具有 Last-Modified
声明,则再次向web服务器请求时带上头。
If-Modified-Since ,表示请求时间。web服务器收到请求后发现有头 If-Modified-Since 则与被请求资源的
最后修改时间进行比对。若最后修改时间较新,说明资源有被改动过,则响应整片资源内容(写在响应消息包体内)
,HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应 HTTP 304 (无需包体,节省浏览),告知浏览器
继续使用所保存的 cache。
Pragma行是为了兼容 HTTP1.0 ,作用与 Cache-Control: no-cache 是一样的
Etag/If-None-Match
Etag :web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定),如果给定URL中
的资源修改,则一定要生成新的Etag值
If-None-Match :当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web
服务器请求时带上头 If-None-Match (Etag的值)。web服务器收到请求后发现有头 If-None-Match 则与被请求
资源的相应校验串进行比对,决定返回200或304。
Etag:
Last-Modified 标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注
文件的修改时间,如果某些文件会被定期生成,当有时内容并没有任何变化,但 Last-Modified 却改变了,导致文
件没法使用缓存有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形 Etag是服务器
自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。 Last-Modified 与
ETag 是可以一起使用的,服务器会优先验证 ETag ,一致的情况下,才会继续比对 Last-Modified ,最后才
决定是否返回304。
用户如果请求获取的数据不是需要后端服务器处理返回,如果我们需要对数据做缓存来提高服务器的处理能力,我们
可以按照如下步骤实现:
1、请求Nginx,Nginx将请求路由给后端服务
2、后端服务查询Redis或者MySQL,再将返回结果给Nginx
3、Nginx将结果存入到Nginx缓存,并将结果返回给用户
4、用户下次执行同样请求,直接在Nginx中获取缓存数据
proxy_cache 是用于 proxy 模式(一般也可称为反代)的缓存功能,proxy_cache 在 Nginx 配置的 http 段、server段(location 段)中分别写入不同的配置。http 段中的配置用于定义 proxy_cache 空间,server 段中的配置用于调用 http 段中的定义,启用对 server 的缓存功能。
属性使用说明
proxy_cache_path:
Example
proxy_cache_path /usr/local/openresty/nginx/cache levels=1:2 keys_zone=openresty_cache:10m
max_size=10g inactive=60m use_temp_path=off;
【作用】指定缓存存储的路径,缓存存储在/usr/local/openresty/nginx/cache目录
【levels=1:2】设置一个两级目录层次结构存储缓存,在单个目录中包含大量文件会降低文件访问速度,因此我们
建议对大多数部署使用两级目录层次结构。如果 levels 未包含该参数,Nginx 会将所有文件放在同一目录中。
【keys_zone=openresty_cache:10m】设置共享内存区域,用于存储缓存键和元数据,例如使用计时器。拥有内存
中的密钥副本,Nginx 可以快速确定请求是否是一个 HIT 或 MISS 不必转到磁盘,从而大大加快了检查速度。
1 MB 区域可以存储大约 8,000 个密钥的数据,因此示例中配置的 10 MB 区域可以存储大约 80,000 个密钥的数
据。
【max_size=10g】设置缓存大小的上限。它是可选的; 不指定值允许缓存增长以使用所有可用磁盘空间。当缓存大
小达到限制时,一个称为缓存管理器的进程将删除最近最少使用的缓存,将大小恢复到限制之下的文件。
【inactive=60m】指定项目在未被访问的情况下可以保留在缓存中的时间长度。在此示例中,缓存管理器进程会自
动从缓存中删除 60 分钟未请求的文件,无论其是否已过期。默认值为 10 分钟(10m)。非活动内容与过期内容
不同。Nginx 不会自动删除缓存 header 定义为已过期内容(例如 Cache-Control:max-age=120)。过期(陈旧)
内容仅在指定时间内未被访问时被删除。访问过期内容时,Nginx 会从原始服务器刷新它并重置 inactive 计时器。
【use_temp_path=off】表示NGINX会将临时文件保存在缓存数据的同一目录中。这是为了避免在更新缓存时,磁
盘之间互相复制响应数据,我们一般关闭该功能。
proxy_cache:
设置是否开启对后端响应的缓存,如果开启的话,参数值就是zone的名称,
比如:proxy_cache openresty_cache;
proxy_cache_valid
针对不同的response code设定不同的缓存时间,如果不设置code,默认为200,301,302,也可以用any指定所有
code。
Example:
【proxy_cache_valid 200 304 10s;】所有200/304响应的数据都缓存10秒。
【proxy_cache_valid any 1m;】所有请求响应的值都缓存1分钟。
proxy_cache_min_uses
指定在多少次请求之后才缓存响应内容,这里表示将缓存内容写入到磁盘。
Example:
【proxy_cache_min_uses 3;】同一个请求达到了3次,才将缓存写入磁盘。
proxy_cache_lock:
默认不开启,开启的话则每次只能有一个请求更新相同的缓存,其他请求要么等待缓存有数据要么限时等待锁释放;
nginx1.1.12才开始有
proxy_cache_key:
缓存文件的唯一key,可以根据它实现对缓存文件的清理操作
我们在 nginx.conf 中添加如下配置
#Nginx代理缓存配置
proxy_cache_path /usr/local/openresty/nginx/cache levels=1:2 keys_zone=openresty_cache:10m max_size=10g inactive=60s use_temp_path=off;
server {
listen 80;
server_name localhost;
#跨域配置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET,POST';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
#配置Nginx缓存 结合Nginx代理缓存配置
location /user {
#启用缓存openresty_cache
proxy_cache openresty_cache;
#针对指定请求缓存
proxy_cache_methods GET;
#设置指定请求会缓存
proxy_cache_valid 200 304 10s;
#最少请求1次才会缓存
proxy_cache_min_uses 3;
#如果并发请求,只有第1个请求会去服务器获取数据
proxy_cache_lock on;
#唯一的key 是否存在key 存在则从缓存重读取数据
proxy_cache_key $host$uri$is_args$args;
# 这个是我本机的一个服务
proxy_pass http://192.168.139.1:18082;
}
#客户端缓存
location / {
#静态文件路径
root /usr/local/server/html;
#缓存10秒
expires 10s;
}
}
此时 /usr/local/openresty/nginx/cache 目录下只有1个temp文件夹。
我们执行3次请求 http://192.168.139.187/user/wangwu ,
我的后台接口
可以发现此时多了一些其他目录,这些目录就是存储每个请求对应的缓存。
很多时候我们如果不想等待缓存的过期,想要主动清除缓存,可以采用第三方的缓存清除模块清除缓存nginx_ngx_cache_purge 。安装nginx的时候,需要添加 purge 模块, purge 模块我们已经下载了,在 /usr/local/server 目录下,添加该模块
–add-module=/usr/local/server/ngx_cache_purge-2.3/ ,这一个步骤我们在安装 OpenRestry 的时候已经实现了。
安装好了后,我们配置一个清理缓存的地址:
#清空nginx缓存 根据key
location ~ /purge(/.*) {
#这里 $1 代表的是 (/.*) 的数据。
proxy_cache_purge openresty_cache $host$1$is_args$args;
}
这里 $1 代表的是 (/.*) 的数据。
每次请求 h o s t host hostkey 就可以删除指定缓存,我们可以先查看缓存文件的可以:
此时访问
此时访问 http://192.168.139.187/purge/user/userinfo/wangwu
此时再查看缓存文件,已经删除了。
参数说明:
$args
参数: $args
解释: HTTP请求中的完整参数。
访问: http://test.itheima.com/192.168.1.200?a=10
返回: "a=10"
$uri
参数: $uri
解释: 表示当前请求的URI,不带任何参数
访问: http://test.itheima.com/user/wangwu?a=10
返回: "/user/wangwu"
$host
参数: $host
解释: 表示客户端请求头部中的Host字段。如果Host字段不存在,则以实际处理的server name名称代替。如果
Host字段中带有端口,如IP:PORT,那么$host会去掉端口
访问: http://test.itheima.com/192.168.1.200?a=10
返回: "test.itheima.com"
$is_args
参数: $is_args
解释: 表示请求中的URL是否带参数,如果带参数,$is_args值为"?"。如果不带参数,则是空字符串
访问: http://test.wanglei.com/192.168.1.200?a=10
返回: "?"
访问: http://test.wanglei.com/192.168.1.200
返回: ""