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. 参考

相关推荐
只因在人海中多看了你一眼2 小时前
分布式缓存 + 数据存储 + 消息队列知识体系
分布式·缓存
Dlwyz3 小时前
redis-击穿、穿透、雪崩
数据库·redis·缓存
Oak Zhang8 小时前
sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
redis·mysql·缓存
门牙咬脆骨9 小时前
【Redis】redis缓存击穿,缓存雪崩,缓存穿透
数据库·redis·缓存
门牙咬脆骨9 小时前
【Redis】GEO数据结构
数据库·redis·缓存
墨鸦_Cormorant10 小时前
使用docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像
redis·nginx·docker
一只爱撸猫的程序猿11 小时前
一个简单的Linux 服务器性能优化案例
linux·mysql·nginx
Dlwyz13 小时前
问题: redis-高并发场景下如何保证缓存数据与数据库的最终一致性
数据库·redis·缓存
DC_BLOG14 小时前
Linux-Nginx虚拟主机
linux·运维·nginx
Stara051114 小时前
Git推送+拉去+uwsgi+Nginx服务器部署项目
git·python·mysql·nginx·gitee·github·uwsgi