18个必知的Nginx缓存代理技巧,全掌握成运维老司机?
我们都知道应用程序和网站的性能是他们成功的关键因素。但是应用程序或网站表现更好的过程并不总是很清楚。代码质量和基础架构当然至关重要,但在许多情况下,可以通过专注于一些非常基本的应用程序的交付技术,对应用程序的最终用户体验进行大量改进。
其中一个例子是在应用程序栈中实现和优化缓存。在教程中介绍的技术可以帮助新手和高级用户使用 Nginx 中包含的内容缓存功能,从而获得更好的性能。
概览
如何设置和配置基本缓存
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g
inactive=60m use_temp_path=off;
server {
# ...
location / {
proxy_cache my_cache;
proxy_pass http://my_upstream;
}
}
-
缓存的本地磁盘目录称为 /path/to/cache/。 -
levels 在/path/to/cache/ 下设置一个两级目录层次结构。在单个目录中包含大量文件会降低文件访问速度,因此我们建议对大多数部署使用两级目录层次结构。如果 levels 未包含该参数,Nginx 会将所有文件放在同一目录中。 -
keys_zone 设置共享内存区域,用于存储缓存键和元数据,例如使用计时器。拥有内存中的密钥副本,Nginx 可以快速确定请求是否是一个 HIT 或 MISS 不必转到磁盘,从而大大加快了检查速度。1 MB 区域可以存储大约 8,000 个密钥的数据,因此示例中配置的 10 MB 区域可以存储大约 80,000 个密钥的数据。 -
max_size 设置缓存大小的上限(在本例中为 10 千兆字节)。它是可选的; 不指定值允许缓存增长以使用所有可用磁盘空间。当缓存大小达到限制时,一个称为缓存管理器的进程将删除最近最少使用的缓存,将大小恢复到限制之下的文件。 inactive 指定项目在未被访问的情况下可以保留在缓存中的时间长度。在此示例中,缓存管理器进程会自动从缓存中删除 60 分钟未请求的文件,无论其是否已过期。默认值为 10 分钟(10m)。非活动内容与过期内容不同。Nginx 不会自动删除缓存 header 定义为已过期内容(例如 Cache-Control:max-age=120)。过期(陈旧)内容仅在指定时间内未被访问时被删除。访问过期内容时,Nginx 会从原始服务器刷新它并重置 inactive 计时器。
Nginx 首先将发往高速缓存的文件写入临时存储区域,use_temp_path=off 指令指示 NGINX 将它们写入将被高速缓存的相同目录。我们建议您将此参数设置 off 为避免在文件系统之间进行不必要的数据复制。use_temp_path 在 Nginx 1.7.10 中引入。
当上游服务器关闭()时提供缓存内容
location / {
# ...
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
}
如何提高缓存性能
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g
inactive=60m use_temp_path=off;
server {
# ...
location / {
proxy_cache my_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 3;
proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_pass http://my_upstream;
}
}
跨多个硬盘拆分缓存
proxy_cache_path /path/to/hdd1 levels=1:2 keys_zone=my_cache_hdd1:10m
max_size=10g inactive=60m use_temp_path=off;
proxy_cache_path /path/to/hdd2 levels=1:2 keys_zone=my_cache_hdd2:10m
max_size=10g inactive=60m use_temp_path=off;
split_clients $request_uri $my_cache {
50% “my_cache_hdd1”;
50% “my_cache_hdd2”;
}
server {
# ...
location / {
proxy_cache $my_cache;
proxy_pass http://my_upstream;
}
}
如何对 Nginx Cache 进行检测
add_header X-Cache-Status $upstream_cache_status;
此示例 X-Cache-Status 在响应客户端时添加 HTTP 标头。以下是可能的值 $upstream_cache_status:
MISS - 在缓存中找不到响应,因此从原始服务器获取响应。然后缓存响应。
BYPASS - 响应是从原始服务器获取的,而不是从缓存中提供的,因为请求与 proxy_cache_bypass 指令匹配
EXPIRED - 缓存中的条目已过期。响应包含来自原始服务器的新内容。
STALE- 内容过时,因为源服务器未正确响应但 proxy_cache_use_stale 已配置。
UPDATING- 内容过时,因为条目当前正在更新以响应先前的请求,并且 proxy_cache_use_stale updating 已配置。
REVALIDATED- proxy_cache_revalidate 指令已启用,Nginx 验证当前缓存的内容是否仍然有效通过(If-Modified-Since或If-None-Match)。
-
HIT - 响应直接来自有效的缓存
Nginx 如何确定是否要缓存响应
Nginx 是否可以忽略 Cache-Control
location /images/ {
proxy_cache my_cache;
proxy_ignore_headers Cache-Control;
proxy_cache_valid any 30m;
# ...
}
Nginx 忽略 /images/ Cache-Control 下所有内容的标题。该指令强制缓存数据到期,如果忽略标头则需要。Nginx 不会缓存没有过期的文件。
Nginx 是否可以忽略 Set-Cookie
使用 proxy_ignore_headers 指令即可。
Nginx 如何缓存 POST 请求
此示例启用了POST请求的缓存。
Nginx 如何缓存动态内容
如何不使用 Nginx 缓存
location / {
proxy_cache_bypass $cookie_nocache $arg_nocache;
# ...
}
该指令定义了 Nginx 立即从源服务器请求内容的请求类型,而不是首先尝试在缓存中找到它。这有时被称为通过缓存 “打孔”。
Nginx 使用什么缓存密钥
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g
inactive=60m use_temp_path=off;
server {
# ...
location / {
proxy_cache my_cache;
proxy_pass http://my_upstream;
}
}
使用 Cookie 作为我的缓存密钥的一部分
缓存键可以配置为任意值,例如:
proxy_cache_key $proxy_host$request_uri$cookie_jessionid;
Nginx 使用 ETag 标头
在 Nginx 1.7.3 及更高版本中,ETag 标头完全支持 If-None-Match。
Nginx 如何处理字节范围请求
Nginx 如何处理 Pragma 标头
location /images/ {
proxy_cache my_cache;
proxy_cache_bypass $http_pragma;
# ...
}
Nginx 是否支持标头 stale-while-revalidate 和 stale-if-error 以及扩展的 Cache-Control
Nginx 是否支持 Vary 标头
Nginx 1.7.7 以及更高版本中是支持 Vary 标头的 。