缓存架构设计之——Nginx缓存

前言
为了提升网站的整体性能,我们一般会采用缓存,从宏观层面来说,会采用浏览器缓存和后端焕春,Nginx处于Web网站的服务最外层,而且支持浏览器缓存配置和后端数据缓存,用它来做部分部分数据缓存,效率更高。
Web缓存是可以自动保存常见的文档副本打HTTP设备。当Web请求抵达缓存时,如果本地有"已缓存的"副本,就可以从本地设备而不是服务器中提取这个文档。

1、OpenResty安装

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。
缓存架构设计之——Nginx缓存_第1张图片

2、 浏览器缓存

客户端侧缓存一般指的是浏览器缓存、app缓存等等,目的就是加速各种静态资源的访问,降低服务器压力。
我们通过配置Nginx设置网页缓存信息,从而降低用户对服务器频繁访问造成的巨大压力。我们先配置一个案例,再基于案例去讲解Nginx缓存

2.1、 Nginx Web缓存配置

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
缓存架构设计之——Nginx缓存_第2张图片
第二次访问 192.168.139.187/1.html
缓存架构设计之——Nginx缓存_第3张图片

2.2 、Http缓存控制头

缓存架构设计之——Nginx缓存_第4张图片
参数说明

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。

2.3 代理缓存

用户如果请求获取的数据不是需要后端服务器处理返回,如果我们需要对数据做缓存来提高服务器的处理能力,我们
可以按照如下步骤实现:

1、请求Nginx,Nginx将请求路由给后端服务
2、后端服务查询Redis或者MySQL,再将返回结果给Nginx
3、Nginx将结果存入到Nginx缓存,并将结果返回给用户
4、用户下次执行同样请求,直接在Nginx中获取缓存数据

2.3.1、 proxy_cache

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,可以根据它实现对缓存文件的清理操作

2.3.2、 缓存操作

我们在 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缓存_第5张图片

可以发现此时多了一些其他目录,这些目录就是存储每个请求对应的缓存。

缓存架构设计之——Nginx缓存_第6张图片
进去之后可以看到我们的缓存信息
缓存架构设计之——Nginx缓存_第7张图片

3、ngx_cache_purage

很多时候我们如果不想等待缓存的过期,想要主动清除缓存,可以采用第三方的缓存清除模块清除缓存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 就可以删除指定缓存,我们可以先查看缓存文件的可以:
缓存架构设计之——Nginx缓存_第8张图片
此时访问
此时访问 http://192.168.139.187/purge/user/userinfo/wangwu
缓存架构设计之——Nginx缓存_第9张图片
此时再查看缓存文件,已经删除了。
参数说明:

$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
	返回: ""

你可能感兴趣的:(分布式缓存架构设计,缓存,nginx)