Nginx 是一款强大的 Web 应用软件,常用做托管网站、反向代理或负载均衡。随着时间的推移,Nginx在常用的 Web 服务器软件中已然超越 Apache,这主要是得益于其优越的性能以及配置便捷性。
但是,当部署为后端服务器的前端时,大多数时候都会错过一个关键功能, 那就是 Nginx超越HAProxy 的静态资源【缓存能力】,这可以通过将数据写入磁盘来实现,也可以直接用内存来缓存数据以获取更加卓越的性能。
在下面的教程中,您将看到一些Nginx缓存的配置和调优代码示例。
系统环境要求
操作系统:任何安装了 Nginx 的 Linux 操作系统。
用户帐户:具有 sudo 或 root 访问权限的用户帐户。
创建 Nginx 磁盘缓存
在第一个示例中,您将创建一个目录,并将一个区域添加到您的 Nginx server
块,并将传统的静态文件缓存到磁盘。 注意,从长远来看,如果您不使用高性能的固态硬盘(SSD),缓存到磁盘有时可能不是一个好主意。 此外,即使使用 SSD,持续写入也会缩短预期寿命,具体取决于硬盘驱动器的使用年限和质量。
首先,创建存放缓存数据的目录:
sudo mkdir -p /cache/tmpfs/
接下来,将以下内容添加到您的nginx配置文件server
块中。可以修改配置模板文件中的现有的代理服务器块,并添加额外内容。
proxy_cache_path /cache/nginx/tmpfs levels=1:2 keys_zone=my_zone:100m max_size=10g inactive=60m use_temp_path=off;
server {
...
location / {
proxy_cache my_zone;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_cache_valid 404 302 1m;
proxy_cache_valid 200 1d;
proxy_http_version 1.1;
add_header X-Cache-Status $upstream_cache_status;
}
...
}
注意,确保 proxy_cache_path
位于配置文件中的http
部分而不是server
块。 此外,文件路径必须是绝对路径,否则将不起作用。
以下Nginx部分术语说明。
- keys_zone:设置一个共享内存区域,用于存储缓存键和元数据。在内存中拥有键副本使 NGINX 能够快速确定请求是命中缓存 (HIT) 还是未命中缓存 (MISS),而无需转到磁盘,从而大大加快了检索速度。一个 1MB 区域可以存储大约 8,000 个键的数据,因此示例中配置的 10MB 区域可以存储大约 80,000 个键的数据。
- inactive:指定数据可以在缓存中保留多长时间未访问而不删除。在此示例中,缓存管理器进程会自动从缓存中删除 60 分钟未请求的文件,无论它是否已过期。默认值为 10 分钟 (10m)。非活动内容与过期内容不同。 NGINX 不会自动删除缓存控制标头定义的过期内容(例如 Cache-Control:max-age=120)。过期(陈旧)内容仅在非活动指定的时间内未被访问时才会被删除。当访问过期内容时,NGINX 从源服务器刷新它并重置非活动计时器。
- max_size:设置缓存大小的上限(在本例中为 10 GB)。它是可选的;不指定值允许缓存增长以使用所有可用磁盘空间。当缓存大小达到限制时,缓存管理器进程会删除最近最少使用的文件,以使缓存大小恢复到限制之下。
- proxy_cache_path:您创建的缓存文件夹的文件路径。
- add_header X-Cache-Status $upstream_cache_status:在响应客户端时添加一个 X-Cache-Status HTTP 标头
- proxy_cache_revalidate <on|off>:指示 NGINX 在从源服务器刷新内容时使用条件 (GET) 请求。如果客户端请求缓存控制标头定义的已缓存但已过期的项目,NGINX 会在它发送到源服务器的 (GET) 请求的标头中包含 (If-Modified-Since) 字段。这节省了带宽,因为只有在 NGINX 最初缓存它时附加到文件的 (Last-Modified) 标头中记录的时间以来文件有修改,服务器才发送完整的项目。
- proxy_cache_min_uses <number>:设置一个项目在 NGINX 缓存之前必须被客户端请求的次数。如果缓存不断被填满,这很有用,因为它确保只有最常访问的项目被添加到缓存中。默认情况下 (proxy_cache_min_uses) 设置为 1。
- proxy_cache_background_update <on|off>:(proxy_cache_use_stale)指令的(更新)参数,结合启用(proxy_cache_background_update)指令,指示NGINX在客户端请求过期或正在更新的项目时,在完全下载更新的文件之前,所有请求都会返回陈旧文件。所有更新都将在后台完成。
- proxy_cache_lock <on|off>:启用 (proxy_cache_lock) 后,如果多个客户端请求缓存未命中 (MISS),则仅允许这些请求中的第一个去原始服务器取数据。其余请求等待该请求得到满足后,再从缓存中提取文件。如果不启用 (proxy_cache_lock),所有导致缓存未命中的请求都会直接发送到源服务器。
内存中的 Nginx 缓存
如果您的服务器有充足的资源,缓存到内存(RAM)总是比将文件缓存到磁盘更好,这甚至适用于最先进的 SSD 驱动器。
首先,创建一个用于RAM缓存的新目录:
sudo mkdir -p /cache/nginx/tmpfs
然后,使用以下命令将创建的目录(tmpfs)挂载到 RAM 中:
sudo mount -t tmpfs -o size=2g tmpfs /cache/nginx/tmpfs
这会在 RAM 中挂载 (/data/nginx/tmpfs),并分配 2 GB空间。缓存空间大小可以根据服务内存大小做调整。
如果需要卸载(unmount),执行以下代码:
sudo umount /cache/nginx/ramcache
要使用 Nginx 完成 RAM 缓存设置,您需要将以下内容添加到 (/etc/fstab),以便当服务器自动重新启动时,RAM 缓存目录会重新创建。
使用 nano 打开 (/etc/fstab) 文件:
sudo nano /etc/fstab
输入以下内容并调整到您的缓存位置和大小:
tmpfs /cache/nginx/tmpfs tmpfs defaults,size=1g 0 0
Nginx 代理缓冲
如果您使用 Nginx 反向代理,提高性能的一个好方法是使用代理缓冲。 这与 Nginx 如何处理从代理服务器接收到的响应的方式有关。 它意味着不会为每个客户端请求查询代理服务器,但如果缓存的数据仍然被认为是有效的(生命周期尚未过去),则从缓存中提供数据。
下面是可用示例:
#Enables or disables buffering of responses from the proxied server.
proxy_buffering on;
#proxy buffer cache sizes
proxy_buffers 4 256k;
proxy_buffer_size 128k;
proxy_busy_buffers_size 256k;
WordPress缓存
上面的例子在 WordPress 网站上效果很好。 但是,需要一些额外的规则来确保正常有效。
首先,将下列代码粘贴在缓存在配置文件server
块(location)区域上方:
set $skip_cache 0;
# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache uris containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|^/feed/*|/tag/.*/feed/*|index.php|/.*sitemap.*\.(xml|xsl)") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
}
如您所见,我们正在跳过(POST)请求的缓存,查询字符串应始终转到 PHP,不缓存包含一些日常内容(如提要、站点地图等)的所有 URL。
接下来,在缓存配置的location中添加以下两行:
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
对于想要查看完整示例的新用户,请在工作环境中查看以下内容:
location / {
proxy_pass http://webserver;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache my_zone;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_cache_valid 404 302 1m;
proxy_cache_valid 200 31d;
add_header X-Cache-Status $upstream_cache_status;
proxy_buffering on;
proxy_buffers 256 16k;
proxy_buffer_size 32k;
proxy_http_version 1.1;
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
}
}
Nginx浏览器缓存
浏览器缓存是减少服务器负载的好方法,尤其是在您运行博客或其他类似内容时。 您可以为动态内容经常变化的购物和论坛设置延长时间。
最常见的浏览器缓存示例如下。 在您的缓存配置server
块中输入此内容。
# assets, media
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
expires 365d;
access_log off;
}
# svg, fonts
location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
add_header Access-Control-Allow-Origin "*";
expires 365d;
access_log off;
}
为了节省磁盘 IO 和日志记录,您可以在访问日志中声明关闭这些资源,以在您遇到过长的加载时间问题时提高服务器的性能。
总结
在本教程中,您学习了如何基于文件和 RAM 使用 Nginx 代理缓存。 有关 Nginx 缓存的更多信息,请访问 Nginx 缓存文档以了解更多信息,因为它还有非常丰富的附加选项。也就是说还可以做更多精细化的调优,因为这个简单教程指南仅仅做了个入门级介绍。