重新思考Nginx中使用map指令进行缓存生成

7 min

language: ja bn en es hi pt ru zh-cn zh-tw

大家好,我是无能。
如果频繁更新博客文章,就不希望在文章更新时加载旧的缓存。
但是,我希望尽可能从缓存中提供内容,所以来思考一下。

停止使用if进行缓存判断

在类似这样的文章中介绍的,通过设置$do_not_cache等标志,然后使用if语句来改变缓存内容的做法,现在似乎已被弃用。
介绍一种架构,即使Nginx的代理缓存冗余化也能通用,让WordPress飞速运行(OpenResty+Redis)

话虽如此,那在哪里进行缓存判断呢?

map指令用于判断Nginx变量的内容,并将结果作为值赋给另一个变量。

2022-03-01 尝试过滤Nginx日志

在调查过程中,发现了一个非常简单的语法。
Adding location-block to cache files makes those files return 404

map $uri $expire {
    ~\.(?:j|cs)s$                      180d;
    ~\.(?:jpe?g|png|webp|woff2?|ttf)$  365d;
    default                            off;
}
map $uri $cache_control {
    ~\.(?:js|css|jpe?g|png|webp|woff2?|ttf)$  public;
}
server {
    ...
    expires $expire;
    add_header Pragma $cache_control;
    add_header Cache-Control $cache_control;
    ...
}

原来如此,很清楚。

目标缓存

基本上,除了html文件之外,其他文件都应该保持较长的缓存时间,而html文件只需稍作缓存即可。
这是因为在遇到DOS或洪水攻击时,希望Nginx服务器能够尽可能地响应。
暂时尝试如下设置。

map $uri $expire {
    ~\.(jpg|jpeg|png|webp|gif|mp4|css|js|ico|woff2)(\?.*)?$ 365d;
    ~\.html$ 5m;
}

map $uri $cache_control {
    ~\.(jpg|jpeg|png|webp|gif|mp4|css|js|ico|woff2)(\?.*)?$ public;
    ~\.html$ public;
}

现在,执行nginx -tservice nginx restart,然后用curl进行测试。

如果请求URI中不存在html,就不会缓存...

看来,由于是以html文件作为键进行缓存的,所以它不会尝试按域名进行缓存。

alleycat:[haturatu]:~/git$ curl -I https://soulminingrig.com
HTTP/2 200 
server: nginx/1.27.0
date: Sat, 23 Nov 2024 12:20:55 GMT
content-type: text/html
content-length: 15699
vary: Accept-Encoding
last-modified: Sat, 23 Nov 2024 12:08:31 GMT
etag: "3d53-627935ba8f789"
accept-ranges: bytes
vary: Accept-Encoding
content-security-policy: upgrade-insecure-requests
alt-svc: h3=":443"; ma=86400
x-content-type-options: nosniff

alleycat:[haturatu]:~/git$ curl -I https://soulminingrig.com/index.html
HTTP/2 200 
server: nginx/1.27.0
date: Sat, 23 Nov 2024 12:21:00 GMT
content-type: text/html
content-length: 15699
vary: Accept-Encoding
last-modified: Sat, 23 Nov 2024 12:08:31 GMT
etag: "3d53-627935ba8f789"
accept-ranges: bytes
vary: Accept-Encoding
expires: Sat, 23 Nov 2024 12:26:00 GMT
cache-control: max-age=300
content-security-policy: upgrade-insecure-requests
alt-svc: h3=":443"; ma=86400
x-content-type-options: nosniff
pragma: public
cache-control: public

当执行curl -I https://soulminingrig.com时,cache-control信息缺失,这意味着它没有被纳入缓存判断。
实际上显示的是index.html,但Nginx方面并未将其识别为判断依据,所以这次尝试这样做。

map $uri $expire {
    ~\.(jpg|jpeg|png|webp|gif|mp4|css|js|ico|woff2)(\?.*)?$ 365d;
    ~\.html$ 5m;
    ~\.*$ 5m;
}

map $uri $cache_control {
    ~\.(jpg|jpeg|png|webp|gif|mp4|css|js|ico|woff2)(\?.*)?$ public;
    ~\.html$ public;
    ~\.*$ public;
}

这样一来,无论如何,正则表达式都会让任何内容缓存5分钟。
再次尝试curl -I

alleycat:[haturatu]:~/git$ curl -I https://soulminingrig.com
HTTP/2 200 
server: nginx/1.27.0
date: Sat, 23 Nov 2024 12:44:43 GMT
content-type: text/html
content-length: 15699
vary: Accept-Encoding
last-modified: Sat, 23 Nov 2024 12:08:31 GMT
etag: "3d53-627935ba8f789"
accept-ranges: bytes
vary: Accept-Encoding
expires: Sat, 23 Nov 2024 12:49:43 GMT
cache-control: max-age=300
content-security-policy: upgrade-insecure-requests
alt-svc: h3=":443"; ma=86400
x-content-type-options: nosniff
pragma: public
cache-control: public

alleycat:[haturatu]:~/git$ curl -I https://soulminingrig.com/top.png
HTTP/2 200 
server: nginx/1.27.0
date: Sat, 23 Nov 2024 12:44:47 GMT
content-type: image/png
content-length: 46584
vary: Accept-Encoding
last-modified: Sat, 23 Nov 2024 12:08:31 GMT
etag: "b5f8-627935ba12787"
accept-ranges: bytes
expires: Sun, 23 Nov 2025 12:44:47 GMT
cache-control: max-age=31536000
content-security-policy: upgrade-insecure-requests
alt-svc: h3=":443"; ma=86400
x-content-type-options: nosniff
pragma: public
cache-control: public

alleycat:[haturatu]:~/git$ curl -I https://soulminingrig.com/index.html
HTTP/2 200 
server: nginx/1.27.0
date: Sat, 23 Nov 2024 12:44:51 GMT
content-type: text/html
content-length: 15699
vary: Accept-Encoding
last-modified: Sat, 23 Nov 2024 12:08:31 GMT
etag: "3d53-627935ba8f789"
accept-ranges: bytes
vary: Accept-Encoding
expires: Sat, 23 Nov 2024 12:49:51 GMT
cache-control: max-age=300
content-security-policy: upgrade-insecure-requests
alt-svc: h3=":443"; ma=86400
x-content-type-options: nosniff
pragma: public
cache-control: public

所有内容都成功地被缓存了。

通过这种缓存方式,配置文件语法变得简洁了许多,而且当需要更改缓存设置时,只需修改map指令即可,这使得操作变得非常方便。
那么,下次再见。

Related Posts