Nginx缓存配置实现CDN加速

Nginx缓存配置实现CDN加速

  • [1. 前言](#1. 前言)
  • [2. 配置介绍](#2. 配置介绍)
    • [2.1 proxy_cache_path](#2.1 proxy_cache_path)
    • [2.2 proxy_cache](#2.2 proxy_cache)
    • [2.3 proxy_cache_key](#2.3 proxy_cache_key)
    • [2.4 proxy_cache_lock](#2.4 proxy_cache_lock)
    • [2.5 proxy_cache_lock_timeout](#2.5 proxy_cache_lock_timeout)
    • [2.6 proxy_cache_lock_age](#2.6 proxy_cache_lock_age)
    • [2.7 proxy_cache_min_uses](#2.7 proxy_cache_min_uses)
    • [2.8 proxy_cache_purge](#2.8 proxy_cache_purge)
    • [2.9 proxy_cache_valid](#2.9 proxy_cache_valid)
  • [3. 强制分片](#3. 强制分片)
  • [4. 配置示例](#4. 配置示例)
  • [5. 参考](#5. 参考)

1. 前言

Nginx缓存可以作为作为 CDN 节点实现访问文件的加速,可以极大减轻后端服务的带宽和机器负载。

本文介绍如何配置Nginx作为一个文件访问的缓存服务。

2. 配置介绍

2.1 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_key MD5计算而来。

  • path 定义缓存的路径
  • levels 定义缓存目录的深度,最多3层,例如:levels=1:2:2, 定义每层目录使用的字母长度;cache_key计算的MD5是 c/29/b7/f54b2df7773722d382f4809d65029c,则缓存文件的相对路径是:c/29/b7/f54b2df7773722d382f4809d65029c
  • use_temp_path 是否使用临时目录
  • keys_zone 活动密钥和数据信息都存储在一个共享内存区域中,name为名称,size为个数限制;
  • inactive 在参数指定的时间内未访问的缓存数据将从缓存中删除。默认为10分钟;
  • max_size 特殊的"缓存加载器"进程,设置的最大缓存大小,当超过该大小或可用空间不足时,它会删除最近最少使用的数据;
  • min_free 最小可用空间量
  • loader_files 启动一分钟后,特殊的"缓存加载器"进程被激活。它将有关文件系统上存储的先前缓存数据的信息加载到缓存区域中。加载也是以迭代方式完成的。在一次迭代中,最多loader_files加载 100 个项目(默认情况下为 100 个)
  • loader_threshold 一次迭代的持续时间受参数限制 loader_threshold(默认情况下为 200 毫秒);

注意:该参数需要定义在 http 模块下,能定义在 location 中。

以下其他参数可以定义在location。

2.2 proxy_cache

conf 复制代码
Syntax:  proxy_cache zone | off;
Default: proxy_cache off;

其中zone就是用于缓存的共享内存区域,在 proxy_cache_path中由keys_zone的name定义,同一个区域可以在多个地方使用。

2.3 proxy_cache_key

conf 复制代码
Syntax:  proxy_cache_key string;
Default: proxy_cache_key $scheme$proxy_host$request_uri;

定义缓存的键,例如:
proxy_cache_key "$host$request_uri $cookie_user";

默认情况下,该指令的值接近字符串:
proxy_cache_key $scheme$proxy_host$uri$is_args$args;

2.4 proxy_cache_lock

conf 复制代码
Syntax:  proxy_cache_lock on | off;
Default: proxy_cache_lock off;

启用后,每次只允许一个请求通过将请求传递到代理服务器,同一缓存元素的其他请求将等待响应出现在缓存中或释放此元素的缓存锁,最长不超过 proxy_cache_lock_timeout 指令设置的时间 。

2.5 proxy_cache_lock_timeout

conf 复制代码
Syntax:	 proxy_cache_lock_timeout time;
Default: proxy_cache_lock_timeout 5s;

超时后,请求将被传递给代理服务器,但响应不会被缓存。

2.6 proxy_cache_lock_age

conf 复制代码
Syntax:  proxy_cache_lock_age time;
Default: proxy_cache_lock_age 5s;

设置的时间内,如果传递给代理服务器以填充新缓存元素的最后一个请求尚未完成,则可能会向代理服务器传递另一个请求。一般设置 <= proxy_cache_lock_timeout 。

2.7 proxy_cache_min_uses

conf 复制代码
Syntax:  proxy_cache_min_uses number;
Default: proxy_cache_min_uses 1;

设置请求的数量达到一定次数之后响应将被缓存。

2.8 proxy_cache_purge

conf 复制代码
Syntax:  proxy_cache_purge string ...;

定义请求在何种条件下将被视为缓存清除请求,例如:
proxy_cache_purge PURGE

可通过 curl -X PURGE 进行对文件清除缓存。

2.9 proxy_cache_valid

conf 复制代码
Syntax:  proxy_cache_valid [code ...] time;

为不同的响应代码设置缓存时间,例如:

proxy_cache_valid 200 304 10m;
proxy_cache_valid 404      1m;

3. 强制分片

在以下场景下:

  • 若是请求的文件大小1G,失败重试的代价稍微较大;
  • 若是请求header使用了 Range: bytes=1024-2048 获取片段的场景;

可以在缓存的基础上,增加分片缓存,优势有:

  • 当大文件缓存时,失败后减少重试的流量,只需要重试分片到后端服务;
  • 也能解决后端代码框架 max_body_size 等类似的配置限制,通过分片从后端服务获取文件;
  • 请求header携带Range时,不用获取整个原文件大小,减少对后端的请求;

若是支持强制分片,需要 ngx_http_slice_module 模块的支持。

该模块不是默认构建的,需要通过 --with-http_slice_module 配置参数启用。

示例:

location / {
    slice             1m;
    proxy_cache       cache;
    proxy_cache_key   $uri$is_args$args$slice_range;
    proxy_set_header  Range $slice_range;
    proxy_cache_valid 200 206 1h;
    proxy_pass        http://localhost:8000;
}

注意:有如下配置是必须的:

  • proxy_cache_key 必须带上 $slice_range
  • proxy_cache_valid 状态码缓存需要加上 206
  • proxy_set_header 新增或者改变,到后端的Range统一为slice的大小;

增加了 slice 也有一定的缺点

当使用 curl -X PURGE 请求文件地址清除缓存的时候,默认只清除第一个分片的缓存,需要前端增加 curl -X PURGE -r 1048576-2097151 按照Range清除缓存。

其中Range 1048576-2097151 表示范围 1m-2m ,必须是 slice 值的倍数。

4. 配置示例

conf 复制代码
http {
    # ...
    # 定义缓存路径、zone等
    proxy_cache_path /data/proxycache levels=1:2:2 keys_zone=cache-hdd:1024m max_size=1024g inactive=48h use_temp_path=off;

    server {

    	# 定义缓存使用的zone空间
        proxy_cache cache-hdd;

        location / {
        	# 强制启用 Accept-Ranges
            proxy_force_ranges on;
            # 强制分片
            slice 100m;
            proxy_set_header Range $slice_range;
            # 缓存的key需要带上分片的range
            proxy_cache_key "$uri$slice_range";
            # 定义可以清除缓存
            proxy_cache_purge PURGE;
            # 文件访问了3次才将响应缓存下来
            proxy_cache_min_uses 3;
			# 对并发的请求,设置时间段内只发一个请求到后端
            proxy_cache_lock on;
            proxy_cache_lock_age 60s;
            proxy_cache_lock_timeout 60s;
			# 对不同状态码定义缓存时间
	        proxy_cache_valid 200 206 304 48h;
    	    proxy_cache_valid 404 1s;
			# 在header中增加 MISS/HIT 标识
	        add_header X-Cache-Status $upstream_cache_status;
    		# 代理到后端
            proxy_pass http://domain;
        }
    }
}

5. 参考

相关推荐
qq_3720068641 分钟前
浏览器http缓存问题
网络协议·http·缓存
计算机毕设定制辅导-无忧学长44 分钟前
Redis 初相识:开启缓存世界大门
数据库·redis·缓存
爱吃南瓜的北瓜1 小时前
双重判定锁来解决缓存击穿问题
缓存
Rverdoser1 小时前
redis延迟队列
数据库·redis·缓存
weisian1512 小时前
Redis篇--常见问题篇6--缓存一致性1(Mysql和Redis缓存一致,更新数据库删除缓存策略)
数据库·redis·缓存
记得开心一点嘛3 小时前
高并发处理 --- Caffeine内存缓存库
缓存·caffeine
栗子~~14 小时前
集成 jacoco 插件,查看单元测试覆盖率
缓存·单元测试·log4j
苹果醋317 小时前
Golang的文件加密工具
运维·vue.js·spring boot·nginx·课程设计
Hello.Reader1 天前
Redis热点数据管理全解析:从MySQL同步到高效缓存的完整解决方案
redis·mysql·缓存
麦香--老农1 天前
windows 钉钉缓存路径不能修改 默认C盘解决方案
缓存·钉钉