团队博客
Nginx 实现缓存
唐增伟 2023-08
一. Nginx 的介绍
众所周知,Nginx 能提供静态服务,同时也能够提供反向代理,同时也能够提供缓存服务。结合 lua 发展而来的 OpenResty 能提供强大的 API 服务,所以说,Nginx 与高速发展的现代互联网相适应,因此,我们也应该学好 Nginx。
二. 缓存介绍
缓存的分类 缓存分为客户端缓存和服务端缓存,当然,每种缓存都有自己的优缺点。对于客户端缓存来说,可以直接读取本地的内容,没有网络消耗,响应最快,缺点是仅仅对该单一的用户生效。而服务端缓存能够对所有用户生效,而且能降低上游服务器的压力,缺点是用户仍然有网络消耗。
三. Nginx 的安装
本人使用的系统是 FreeBSD13.1,各位也可以根据自己的需要选择适合自己系统的 Nginx 版本进行安装。
1.安装 Nginx 包
pkg install nginx
2.安装完成后,配置 rc.conf 使 Nginx 可以开机启动
vim /etc/rc.conf 编辑rc.conf文件,添加nginx_enable="YES",保存退出
3.启动 Nginx
service nginx start
4.查看 Nginx 监听的端口
sockstat -4l USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS www nginx 1213 7 tcp4 *:80 *:* root nginx 1210 7 tcp4 *:80 *:* root sendmail 1052 5 tcp4 127.0.0.1:25 *:* root sshd 821 4 tcp4 *:22 *:* root syslogd 714 7 udp4 *:514 *:*
可以看到 nginx 已监听在了 80 端口上,至此 nginx 安装完成。
四. 缓存相关指令及使用
1.proxy_cache 定义用来缓存的内存区域, 下面的 zone 是共享内存名称
语法:proxy_cache zone/off
默认值:proxy_cache off;
上下文:http、srver、location
2.proxy_cache_path 设置缓存的路径和其他其他参数
语法:proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [min_free=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
默认值:proxy_cache_path off;
上下文:http
具体参数说明
可选参数 | 含义 |
---|---|
path | 缓存文件的存放路径 |
level | path 的目录层级 |
use_temp_path | off 直接使用 path 路径;on 使用 proxy_temp_path 路径 |
keys_zone | name 是共享内存名称;size 是共享内存大小 |
inactive | 在指定时间内没有被访问缓存会被清理;默认 10 分钟 |
max_size | 设定最大的缓存空间大小,超过将由 CM(Cache Manager)清理 |
manager_files | CM 清理一次缓存文件,最大清理文件数;默认 100 |
manager_sleep | CM 清理一次后进程的休眠时间;默认 200 毫秒 |
manager_threshold | CM 清理一次最长耗时;默认 50 毫秒 |
loader_files | CL(Cache Loader)载入文件到共享内存,每批最多文件数;默认 100 |
loader_sleep | CL 加载缓存文件到内存后,进程休眠时间;默认 200 毫秒 |
loader_threshold | CL 每次载入文件到共享内存的最大耗时;默认 50 毫秒 |
3.proxy_cache_key 决定保存一个缓存的 key
语法:proxy_cache_key string;
默认值:proxy_cache_key $scheme$proxy_host$request_uri;
上下文:http、server、location
4.proxy_cache_valid 用来设置不同响应状态码的缓存文件的缓存时间
语法: proxy_cache_valid [code ...] time;
默认值: —
上下文: http、server、location
5.upstream_cache_status 变量缓存的状态,如用来查看缓存是否命中
MISS:未命中缓存
HIT:命中缓存
EXPIRED:缓存过期
STALE: 命中了陈旧缓存
REVALIDDATED:Nginx 验证陈旧缓存依然有效
UPDATING:内容陈旧,但正在更新
BYPASS:响应从原始服务器获取
6.proxy_no_cache 定义不将响应保存到缓存中的条件。如果字符串参数中至少有一个值不为空且不等于 0,则响应将不被保存
语法:proxy_no_cache string;
默认值:-
上下文:http、server、location
7.proxy_cache_bypass 定义不从缓存获取响应的条件。如果字符串参数中至少有一个值不是空的,并且不等于 0,那么响应将不会从缓存中获取
语法:proxy_cache_bypass string;
默认值:-
上下文:http、server、location
五. 缓存指令在配置文件中配置使用
1.服务器相关信息 服务器一:freebsd_node1 , IP: 192.168.122.243 , 对外提供 http 服务
服务器二:freebsd_node2 , IP: 192.168.122.27 , 作为 freebsd_node1 的上游应用程序服务器
freebsd_node2 的配置文件
编辑/usr/local/etc/nginx/nginx.conf 文件,添加内容如下,让 nginx 监听在不同端口
server { listen 1010; root /usr/local/www/1010; location / { index index.html index.htm; } } server { listen 1011; root /usr/local/www/1011; location / { index index.html index.htm; } }
在 freebsd_node2 上,不同的虚拟主机目录下,创建如下文件,并写入不同内容
www ls /usr/local/www/1010 cache.txt index.html www ls /usr/local/www/1011 cache.txt index.html
接下来配置 freebsd_node1
编辑 freebsd_node1 的 nginx 配置文件/usr/local/etc/nginx/nginx.conf,设置如下内容
proxy_cache_path /usr/local/nginx/cache_temp levels=2:2 keys_zone=cache_zone:30m max_size=2g inactive=60m use_temp_path=off; upstream cache_server { server 192.168.122.27:1010; server 192.168.122.27:1011; } server { listen 80; server_name www.mytest.com; location / { proxy_cache cache_zone; proxy_cache_valid 200 5m; add_header Nginx-Cache-Status "$upstream_cache_status"; proxy_pass http://cache_server; } }
2.配置好后,启动 Nginx
2.1 首先,我们可以测试下没有开启缓存是什么现象,将缓存相关配置注释
location / { #proxy_cache cache_zone; #proxy_cache_valid 200 5m; #add_header Nginx-Cache-Status "$upstream_cache_status"; proxy_pass http://cache_server; }
向www.mytest.com发起请求,得到如下
for ((i=1;i<=10;i++)); do curl "http://www.mytest.com/cache.txt"; sleep 1; done 1010 cache.txt file 1011 cache.txt file 1010 cache.txt file 1011 cache.txt file 1010 cache.txt file 1011 cache.txt file 1010 cache.txt file 1011 cache.txt file 1010 cache.txt file 1011 cache.txt file
没有使用缓存,发生了轮循
2.2 启用缓存
开启 Nginx 缓存
location / { proxy_cache cache_zone; proxy_cache_valid 200 5m; add_header Nginx-Cache-Status "$upstream_cache_status"; proxy_pass http://cache_server; }
向www.mytest.com发起请求,可以看到
第一次访问,可以看到 Nginx-Cache-Status 显示没有命中
curl www.mytest.com/cache.txt -I HTTP/1.1 200 OK Server: nginx/1.22.0 Date: Thu, 04 Aug 2022 22:33:55 GMT Content-Type: text/plain Content-Length: 20 Connection: keep-alive Last-Modified: Thu, 04 Aug 2022 22:06:55 GMT ETag: "62ec42ff-14" Nginx-Cache-Status: MISS Accept-Ranges: bytes
第二次访问,可以看到 Nginx-Cache-Status 显示为命中
curl www.mytest.com/cache.txt -I HTTP/1.1 200 OK Server: nginx/1.22.0 Date: Thu, 04 Aug 2022 22:33:57 GMT Content-Type: text/plain Content-Length: 20 Connection: keep-alive Last-Modified: Thu, 04 Aug 2022 22:06:55 GMT ETag: "62ec42ff-14" Nginx-Cache-Status: HIT Accept-Ranges: bytes
同时在 freebsd_node1 中也可以看到已有缓存文件出现
在 freebsd_node1 中,查看/usr/local/nginx/cache_temp 目录结构
tree /usr/local/nginx /usr/local/nginx └── cache_temp └── 76 └── d1 └── 608ccf55afd7b17fc84b73d835ecd176 3 directories, 1 file
如果请求文件,可以看到不再轮循,直接使用缓存
在终端执行如下
for ((i=1;i<=10;i++)); do curl "http://www.mytest.com/cache.txt"; sleep 1; done 1011 cache.txt file 1011 cache.txt file 1011 cache.txt file 1011 cache.txt file 1011 cache.txt file 1011 cache.txt file 1011 cache.txt file 1011 cache.txt file 1011 cache.txt file 1011 cache.txt file
六. 配置 Nginx 不缓存特定内容
对于某些更新比较频繁的网页,我们可能不需要缓存,所以接下来我们设置一下如何使 Nginx 不缓存指定内容
1.编辑 freebsd_node1 的 Nginx 配置文件 当请求的 uri 以 txt 结尾时,设置变量值,然后在下面的 proxy_no_cache 中引用
server { listen 80; server_name www.mytest.com; if ( $request_uri ~ \.(txt)$) { set $cookie_name "no cache"; } location / { proxy_cache cache_zone; proxy_no_cache $cookie_name; proxy_cache_valid 200 5m; add_header Nginx-Cache-Status "$upstream_cache_status"; proxy_pass http://cache_server; } }
将缓存文件删除
rm -rf /usr/local/nginx/cache_temp
重启 Nginx
service nginx restart
再发起请求 cache.txt,可以看到发生了轮循
for ((i=1;i<=10;i++)); do curl "http://www.mytest.com/cache.txt"; sleep 1; done 1010 cache.txt file 1011 cache.txt file 1010 cache.txt file 1011 cache.txt file 1010 cache.txt file 1011 cache.txt file 1010 cache.txt file 1011 cache.txt file 1010 cache.txt file 1011 cache.txt file
多次查看响应头,都是未命中
curl www.mytest.com/cache.txt -I HTTP/1.1 200 OK Server: nginx/1.22.0 Date: Thu, 04 Aug 2022 23:39:09 GMT Content-Type: text/plain Content-Length: 20 Connection: keep-alive Last-Modified: Thu, 04 Aug 2022 22:06:55 GMT ETag: "62ec42ff-14" Nginx-Cache-Status: MISS Accept-Ranges: bytes
七. 总结
在缓存为王的互联网时代,学好缓存是非常重要的,当然也有很多实现缓存的方式,这里只是介绍了 Nginx 如何缓存。Nginx 缓存同样也有很多更深的内容,同样需要我们去探索。